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