1use anyhow::{Result, anyhow};
2use base64::prelude::*;
3use std::fmt;
4
5use crate::DataType;
6
7#[derive(Debug, Clone)]
9pub enum Value {
10 Int8(i8),
11 Int16(i16),
12 Int32(i32),
13 Int64(i64),
14 UInt8(u8),
15 UInt16(u16),
16 UInt32(u32),
17 UInt64(u64),
18 Float32(f32),
19 Float64(f64),
20 TimestampNs(i64),
21 Binary(Vec<u8>),
22 String(String),
23 Boolean(bool),
24}
25
26impl PartialEq for Value {
28 fn eq(&self, other: &Self) -> bool {
29 match (self, other) {
30 (Value::Int8(a), Value::Int8(b)) => a == b,
31 (Value::Int16(a), Value::Int16(b)) => a == b,
32 (Value::Int32(a), Value::Int32(b)) => a == b,
33 (Value::Int64(a), Value::Int64(b)) => a == b,
34 (Value::UInt8(a), Value::UInt8(b)) => a == b,
35 (Value::UInt16(a), Value::UInt16(b)) => a == b,
36 (Value::UInt32(a), Value::UInt32(b)) => a == b,
37 (Value::UInt64(a), Value::UInt64(b)) => a == b,
38 (Value::Float32(a), Value::Float32(b)) => a.to_bits() == b.to_bits(),
39 (Value::Float64(a), Value::Float64(b)) => a.to_bits() == b.to_bits(),
40 (Value::TimestampNs(a), Value::TimestampNs(b)) => a == b,
41 (Value::Binary(a), Value::Binary(b)) => a == b,
42 (Value::String(a), Value::String(b)) => a == b,
43 (Value::Boolean(a), Value::Boolean(b)) => a == b,
44 _ => false,
45 }
46 }
47}
48
49impl Eq for Value {}
51
52impl std::hash::Hash for Value {
54 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55 match self {
56 Value::Int8(v) => {
57 0_i8.hash(state);
58 v.hash(state);
59 }
60 Value::Int16(v) => {
61 1_i8.hash(state);
62 v.hash(state);
63 }
64 Value::Int32(v) => {
65 2_i8.hash(state);
66 v.hash(state);
67 }
68 Value::Int64(v) => {
69 3_i8.hash(state);
70 v.hash(state);
71 }
72 Value::UInt8(v) => {
73 4_i8.hash(state);
74 v.hash(state);
75 }
76 Value::UInt16(v) => {
77 5_i8.hash(state);
78 v.hash(state);
79 }
80 Value::UInt32(v) => {
81 6_i8.hash(state);
82 v.hash(state);
83 }
84 Value::UInt64(v) => {
85 7_i8.hash(state);
86 v.hash(state);
87 }
88 Value::Float32(v) => {
89 8_i8.hash(state);
90 v.to_bits().hash(state);
91 }
92 Value::Float64(v) => {
93 9_i8.hash(state);
94 v.to_bits().hash(state);
95 }
96 Value::TimestampNs(v) => {
97 10_i8.hash(state);
98 v.hash(state);
99 }
100 Value::Binary(v) => {
101 11_i8.hash(state);
102 v.hash(state);
103 }
104 Value::String(v) => {
105 12_i8.hash(state);
106 v.hash(state);
107 }
108 Value::Boolean(v) => {
109 13_i8.hash(state);
110 v.hash(state);
111 }
112 }
113 }
114}
115
116impl fmt::Display for Value {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 Value::Int8(v) => write!(f, "{}", v),
120 Value::Int16(v) => write!(f, "{}", v),
121 Value::Int32(v) => write!(f, "{}", v),
122 Value::Int64(v) => write!(f, "{}", v),
123 Value::UInt8(v) => write!(f, "{}", v),
124 Value::UInt16(v) => write!(f, "{}", v),
125 Value::UInt32(v) => write!(f, "{}", v),
126 Value::UInt64(v) => write!(f, "{}", v),
127 Value::Float32(v) => write!(f, "{}", v),
128 Value::Float64(v) => write!(f, "{}", v),
129 Value::TimestampNs(v) => write!(f, "{}", v),
130 Value::Binary(items) => write!(f, "{}", BASE64_STANDARD.encode(items)),
131 Value::String(v) => write!(f, "{}", v),
132 Value::Boolean(v) => write!(f, "{}", v),
133 }
134 }
135}
136
137impl Value {
138 pub fn data_type(&self) -> DataType {
139 match self {
140 Value::Int8(_) => DataType::Int8,
141 Value::Int16(_) => DataType::Int16,
142 Value::Int32(_) => DataType::Int32,
143 Value::Int64(_) => DataType::Int64,
144 Value::UInt8(_) => DataType::UInt8,
145 Value::UInt16(_) => DataType::UInt16,
146 Value::UInt32(_) => DataType::UInt32,
147 Value::UInt64(_) => DataType::UInt64,
148 Value::Float32(_) => DataType::Float32,
149 Value::Float64(_) => DataType::Float64,
150 Value::TimestampNs(_) => DataType::TimestampNs,
151 Value::Binary(_) => DataType::Binary,
152 Value::String(_) => DataType::String,
153 Value::Boolean(_) => DataType::Boolean,
154 }
155 }
156
157 pub fn as_i8(&self) -> Option<i8> {
158 match self {
159 Value::Int8(v) => Some(*v),
160 _ => None,
161 }
162 }
163
164 pub fn as_i16(&self) -> Option<i16> {
165 match self {
166 Value::Int16(v) => Some(*v),
167 _ => None,
168 }
169 }
170
171 pub fn as_i32(&self) -> Option<i32> {
172 match self {
173 Value::Int32(v) => Some(*v),
174 _ => None,
175 }
176 }
177
178 pub fn as_i64(&self) -> Option<i64> {
179 match self {
180 Value::Int64(v) => Some(*v),
181 _ => None,
182 }
183 }
184
185 pub fn as_u8(&self) -> Option<u8> {
186 match self {
187 Value::UInt8(v) => Some(*v),
188 _ => None,
189 }
190 }
191
192 pub fn as_u16(&self) -> Option<u16> {
193 match self {
194 Value::UInt16(v) => Some(*v),
195 _ => None,
196 }
197 }
198
199 pub fn as_u32(&self) -> Option<u32> {
200 match self {
201 Value::UInt32(v) => Some(*v),
202 _ => None,
203 }
204 }
205
206 pub fn as_u64(&self) -> Option<u64> {
207 match self {
208 Value::UInt64(v) => Some(*v),
209 _ => None,
210 }
211 }
212
213 pub fn as_f32(&self) -> Option<f32> {
214 match self {
215 Value::Float32(v) => Some(*v),
216 _ => None,
217 }
218 }
219
220 pub fn as_f64(&self) -> Option<f64> {
221 match self {
222 Value::Float64(v) => Some(*v),
223 _ => None,
224 }
225 }
226
227 pub fn as_timestamp_ns(&self) -> Option<i64> {
228 match self {
229 Value::TimestampNs(v) => Some(*v),
230 _ => None,
231 }
232 }
233
234 pub fn as_binary(&self) -> Option<&Vec<u8>> {
235 match self {
236 Value::Binary(v) => Some(v),
237 _ => None,
238 }
239 }
240
241 pub fn as_str(&self) -> Option<&str> {
242 match self {
243 Value::String(v) => Some(v),
244 _ => None,
245 }
246 }
247
248 pub fn as_bool(&self) -> Option<bool> {
249 match self {
250 Value::Boolean(v) => Some(*v),
251 _ => None,
252 }
253 }
254
255 pub fn as_number(&self) -> Option<serde_json::Number> {
256 match self {
257 Value::Int8(v) => Some(serde_json::Number::from(*v)),
258 Value::Int16(v) => Some(serde_json::Number::from(*v)),
259 Value::Int32(v) => Some(serde_json::Number::from(*v)),
260 Value::Int64(v) => Some(serde_json::Number::from(*v)),
261 Value::UInt8(v) => Some(serde_json::Number::from(*v)),
262 Value::UInt16(v) => Some(serde_json::Number::from(*v)),
263 Value::UInt32(v) => Some(serde_json::Number::from(*v)),
264 Value::UInt64(v) => Some(serde_json::Number::from(*v)),
265 _ => None,
266 }
267 }
268
269 pub fn from_number_as_type(value: &serde_json::Number, data_type: &DataType) -> Option<Value> {
270 match data_type {
271 DataType::Int8 => value
272 .as_i64()
273 .and_then(|v| v.try_into().ok())
274 .map(Value::Int8),
275 DataType::Int16 => value
276 .as_i64()
277 .and_then(|v| v.try_into().ok())
278 .map(Value::Int16),
279 DataType::Int32 => value
280 .as_i64()
281 .and_then(|v| v.try_into().ok())
282 .map(Value::Int32),
283 DataType::Int64 => value.as_i64().map(Value::Int64),
284 DataType::UInt8 => value
285 .as_u64()
286 .and_then(|v| v.try_into().ok())
287 .map(Value::UInt8),
288 DataType::UInt16 => value
289 .as_u64()
290 .and_then(|v| v.try_into().ok())
291 .map(Value::UInt16),
292 DataType::UInt32 => value
293 .as_u64()
294 .and_then(|v| v.try_into().ok())
295 .map(Value::UInt32),
296 DataType::UInt64 => value.as_u64().map(Value::UInt64),
297 _ => None,
298 }
299 }
300
301 pub fn try_from_serde_json_as_type(
302 value: serde_json::Value,
303 data_type: &DataType,
304 ) -> Result<Value> {
305 match (data_type, value) {
306 (DataType::Int8, serde_json::Value::Number(value)) => {
307 let v = value
308 .as_i64()
309 .ok_or(anyhow!("Unable to read number as i64"))?
310 .try_into()?;
311 Ok(Value::Int8(v))
312 }
313 (DataType::Int16, serde_json::Value::Number(value)) => {
314 let v = value
315 .as_i64()
316 .ok_or(anyhow!("Unable to read number as i64"))?
317 .try_into()?;
318 Ok(Value::Int16(v))
319 }
320 (DataType::Int32, serde_json::Value::Number(value)) => {
321 let v = value
322 .as_i64()
323 .ok_or(anyhow!("Unable to read number as i64"))?
324 .try_into()?;
325 Ok(Value::Int32(v))
326 }
327 (DataType::Int64, serde_json::Value::Number(value)) => {
328 let v = value
329 .as_i64()
330 .ok_or(anyhow!("Unable to read number as i64"))?;
331 Ok(Value::Int64(v))
332 }
333 (DataType::UInt8, serde_json::Value::Number(value)) => {
334 let v = value
335 .as_u64()
336 .ok_or(anyhow!("Unable to read number as i64"))?
337 .try_into()?;
338 Ok(Value::UInt8(v))
339 }
340 (DataType::UInt16, serde_json::Value::Number(value)) => {
341 let v = value
342 .as_u64()
343 .ok_or(anyhow!("Unable to read number as i64"))?
344 .try_into()?;
345 Ok(Value::UInt16(v))
346 }
347 (DataType::UInt32, serde_json::Value::Number(value)) => {
348 let v = value
349 .as_u64()
350 .ok_or(anyhow!("Unable to read number as u32"))?
351 .try_into()?;
352 Ok(Value::UInt32(v))
353 }
354 (DataType::UInt64, serde_json::Value::Number(value)) => {
355 let v = value
356 .as_u64()
357 .ok_or(anyhow!("Unable to read number as u64"))?;
358 Ok(Value::UInt64(v))
359 }
360 (DataType::Float32, serde_json::Value::Number(value)) => {
361 let v = value
362 .as_f64()
363 .ok_or(anyhow!("Unable to read number as f64"))?;
364 Ok(Value::Float32(v as f32))
365 }
366 (DataType::Float64, serde_json::Value::Number(value)) => {
367 let v = value
368 .as_f64()
369 .ok_or(anyhow!("Unable to read number as f64"))?;
370 Ok(Value::Float64(v))
371 }
372 (DataType::TimestampNs, serde_json::Value::Number(value)) => {
373 let v = value
374 .as_i64()
375 .ok_or(anyhow!("Unable to read number as i64"))?;
376 Ok(Value::TimestampNs(v))
377 }
378 (DataType::String, serde_json::Value::String(value)) => Ok(Value::String(value)),
379 (DataType::Binary, serde_json::Value::String(value)) => {
380 let decoded = BASE64_STANDARD.decode(value)?;
381 Ok(Value::Binary(decoded))
382 }
383 (DataType::Boolean, serde_json::Value::Bool(value)) => Ok(Value::Boolean(value)),
384 (to_type, from_value) => Err(anyhow!(
385 "Unsupported data type conversion: {:?} to {:?}",
386 from_value,
387 to_type,
388 )),
389 }
390 }
391
392 pub fn try_to_serde_json(value: Value) -> Result<serde_json::Value> {
393 match value {
394 Value::Int8(v) => Ok(serde_json::Value::Number(v.into())),
395 Value::Int16(v) => Ok(serde_json::Value::Number(v.into())),
396 Value::Int32(v) => Ok(serde_json::Value::Number(v.into())),
397 Value::Int64(v) => Ok(serde_json::Value::Number(v.into())),
398 Value::UInt8(v) => Ok(serde_json::Value::Number(v.into())),
399 Value::UInt16(v) => Ok(serde_json::Value::Number(v.into())),
400 Value::UInt32(v) => Ok(serde_json::Value::Number(v.into())),
401 Value::UInt64(v) => Ok(serde_json::Value::Number(v.into())),
402 Value::Float32(v) => serde_json::Number::from_f64(v as f64)
403 .map(serde_json::Value::Number)
404 .ok_or(anyhow!("Unable to convert float32 to serde_json::Value")),
405 Value::Float64(v) => serde_json::Number::from_f64(v)
406 .map(serde_json::Value::Number)
407 .ok_or(anyhow!("Unable to convert float64 to serde_json::Value")),
408 Value::TimestampNs(v) => Ok(serde_json::Value::Number(v.into())),
409 Value::Binary(v) => Ok(serde_json::Value::String(BASE64_STANDARD.encode(v))),
410 Value::String(v) => Ok(serde_json::Value::String(v)),
411 Value::Boolean(v) => Ok(serde_json::Value::Bool(v)),
412 }
413 }
414}