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 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}