polars_core/scalar/
mod.rs

1mod from;
2mod new;
3pub mod reduce;
4
5use std::hash::Hash;
6
7use polars_error::PolarsResult;
8use polars_utils::pl_str::PlSmallStr;
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12use crate::chunked_array::cast::CastOptions;
13use crate::datatypes::{AnyValue, DataType};
14use crate::prelude::{Column, Series};
15
16#[derive(Clone, Debug, PartialEq)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct Scalar {
19    dtype: DataType,
20    value: AnyValue<'static>,
21}
22
23impl Hash for Scalar {
24    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
25        self.dtype.hash(state);
26        self.value.hash_impl(state, true);
27    }
28}
29
30impl Default for Scalar {
31    fn default() -> Self {
32        Self {
33            dtype: DataType::Null,
34            value: AnyValue::Null,
35        }
36    }
37}
38
39impl Scalar {
40    #[inline(always)]
41    pub const fn new(dtype: DataType, value: AnyValue<'static>) -> Self {
42        Self { dtype, value }
43    }
44
45    pub const fn null(dtype: DataType) -> Self {
46        Self::new(dtype, AnyValue::Null)
47    }
48
49    pub fn cast_with_options(self, dtype: &DataType, options: CastOptions) -> PolarsResult<Self> {
50        if self.dtype() == dtype {
51            return Ok(self);
52        }
53
54        // @Optimize: If we have fully fleshed out casting semantics, we could just specify the
55        // cast on AnyValue.
56        let s = self
57            .into_series(PlSmallStr::from_static("scalar"))
58            .cast_with_options(dtype, options)?;
59        let value = s.get(0).unwrap();
60        Ok(Self::new(s.dtype().clone(), value.into_static()))
61    }
62
63    #[inline(always)]
64    pub fn is_null(&self) -> bool {
65        self.value.is_null()
66    }
67
68    #[inline(always)]
69    pub fn is_nan(&self) -> bool {
70        self.value.is_nan()
71    }
72
73    #[inline(always)]
74    pub fn into_value(self) -> AnyValue<'static> {
75        self.value
76    }
77
78    #[inline(always)]
79    pub fn value(&self) -> &AnyValue<'static> {
80        &self.value
81    }
82
83    pub fn as_any_value(&self) -> AnyValue {
84        self.value
85            .strict_cast(&self.dtype)
86            .unwrap_or_else(|| self.value.clone())
87    }
88
89    pub fn into_series(self, name: PlSmallStr) -> Series {
90        Series::from_any_values_and_dtype(name, &[self.as_any_value()], &self.dtype, true).unwrap()
91    }
92
93    /// Turn a scalar into a column with `length=1`.
94    pub fn into_column(self, name: PlSmallStr) -> Column {
95        Column::new_scalar(name, self, 1)
96    }
97
98    #[inline(always)]
99    pub fn dtype(&self) -> &DataType {
100        &self.dtype
101    }
102
103    #[inline(always)]
104    pub fn update(&mut self, value: AnyValue<'static>) {
105        self.value = value;
106    }
107
108    #[inline(always)]
109    pub fn with_value(mut self, value: AnyValue<'static>) -> Self {
110        self.update(value);
111        self
112    }
113}