vortex_scalar/
binary.rs

1use std::sync::Arc;
2
3use vortex_buffer::ByteBuffer;
4use vortex_dtype::{DType, Nullability};
5use vortex_error::{VortexError, VortexExpect as _, VortexResult, vortex_bail, vortex_err};
6
7use crate::{InnerScalarValue, Scalar, ScalarValue};
8
9#[derive(Debug, Hash)]
10pub struct BinaryScalar<'a> {
11    dtype: &'a DType,
12    value: Option<ByteBuffer>,
13}
14
15impl PartialEq for BinaryScalar<'_> {
16    fn eq(&self, other: &Self) -> bool {
17        self.dtype.eq_ignore_nullability(other.dtype) && self.value == other.value
18    }
19}
20
21impl Eq for BinaryScalar<'_> {}
22
23impl PartialOrd for BinaryScalar<'_> {
24    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
25        Some(self.value.cmp(&other.value))
26    }
27}
28
29impl Ord for BinaryScalar<'_> {
30    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
31        self.value.cmp(&other.value)
32    }
33}
34
35impl<'a> BinaryScalar<'a> {
36    #[inline]
37    pub fn dtype(&self) -> &'a DType {
38        self.dtype
39    }
40
41    pub fn value(&self) -> Option<ByteBuffer> {
42        self.value.as_ref().cloned()
43    }
44
45    pub(crate) fn cast(&self, dtype: &DType) -> VortexResult<Scalar> {
46        if !matches!(dtype, DType::Binary(..)) {
47            vortex_bail!("Can't cast binary to {}", dtype)
48        }
49        Ok(Scalar::new(
50            dtype.clone(),
51            ScalarValue(InnerScalarValue::Buffer(Arc::new(
52                self.value
53                    .as_ref()
54                    .vortex_expect("nullness handled in Scalar::cast")
55                    .clone(),
56            ))),
57        ))
58    }
59
60    /// Returns whether its value is non-null and empty, otherwise `None`.
61    pub fn is_empty(&self) -> Option<bool> {
62        self.value.as_ref().map(|v| v.is_empty())
63    }
64}
65
66impl Scalar {
67    pub fn binary(buffer: impl Into<Arc<ByteBuffer>>, nullability: Nullability) -> Self {
68        Self {
69            dtype: DType::Binary(nullability),
70            value: ScalarValue(InnerScalarValue::Buffer(buffer.into())),
71        }
72    }
73}
74
75impl<'a> TryFrom<&'a Scalar> for BinaryScalar<'a> {
76    type Error = VortexError;
77
78    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
79        if !matches!(value.dtype(), DType::Binary(_)) {
80            vortex_bail!("Expected binary scalar, found {}", value.dtype())
81        }
82        Ok(Self {
83            dtype: value.dtype(),
84            value: value.value.as_buffer()?,
85        })
86    }
87}
88
89impl<'a> TryFrom<&'a Scalar> for ByteBuffer {
90    type Error = VortexError;
91
92    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
93        let binary = scalar
94            .as_binary_opt()
95            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?;
96
97        binary
98            .value()
99            .ok_or_else(|| vortex_err!("Cannot extract present value from null scalar"))
100    }
101}
102
103impl<'a> TryFrom<&'a Scalar> for Option<ByteBuffer> {
104    type Error = VortexError;
105
106    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
107        Ok(scalar
108            .as_binary_opt()
109            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?
110            .value())
111    }
112}
113
114impl TryFrom<Scalar> for ByteBuffer {
115    type Error = VortexError;
116
117    fn try_from(scalar: Scalar) -> VortexResult<Self> {
118        Self::try_from(&scalar)
119    }
120}
121
122impl TryFrom<Scalar> for Option<ByteBuffer> {
123    type Error = VortexError;
124
125    fn try_from(scalar: Scalar) -> VortexResult<Self> {
126        Self::try_from(&scalar)
127    }
128}
129
130impl From<&[u8]> for Scalar {
131    fn from(value: &[u8]) -> Self {
132        Scalar::from(ByteBuffer::from(value.to_vec()))
133    }
134}
135
136impl From<ByteBuffer> for Scalar {
137    fn from(value: ByteBuffer) -> Self {
138        Self {
139            dtype: DType::Binary(Nullability::NonNullable),
140            value: ScalarValue(InnerScalarValue::Buffer(Arc::new(value))),
141        }
142    }
143}
144
145impl From<Arc<ByteBuffer>> for Scalar {
146    fn from(value: Arc<ByteBuffer>) -> Self {
147        Self {
148            dtype: DType::Binary(Nullability::NonNullable),
149            value: ScalarValue(InnerScalarValue::Buffer(value)),
150        }
151    }
152}