1use rkyv::{Archive, Deserialize, Serialize};
4use serde::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
5
6#[derive(Debug, Clone, PartialEq, Archive, Serialize, Deserialize, SerdeSerialize, SerdeDeserialize)]
14pub enum Value {
15 Null,
17 Bool(bool),
19 Int32(i32),
21 Int64(i64),
23 Float32(f32),
25 Float64(f64),
27 String(String),
29 Bytes(Vec<u8>),
31 Timestamp(i64),
33 Uuid([u8; 16]),
35 BoolArray(Vec<bool>),
37 Int32Array(Vec<i32>),
39 Int64Array(Vec<i64>),
41 Float32Array(Vec<f32>),
43 Float64Array(Vec<f64>),
45 StringArray(Vec<String>),
47 UuidArray(Vec<[u8; 16]>),
49}
50
51impl Value {
52 pub fn is_null(&self) -> bool {
54 matches!(self, Value::Null)
55 }
56
57 pub fn is_array(&self) -> bool {
59 matches!(
60 self,
61 Value::BoolArray(_)
62 | Value::Int32Array(_)
63 | Value::Int64Array(_)
64 | Value::Float32Array(_)
65 | Value::Float64Array(_)
66 | Value::StringArray(_)
67 | Value::UuidArray(_)
68 )
69 }
70
71 pub fn as_bool(&self) -> Option<bool> {
73 match self {
74 Value::Bool(b) => Some(*b),
75 _ => None,
76 }
77 }
78
79 pub fn as_i32(&self) -> Option<i32> {
81 match self {
82 Value::Int32(i) => Some(*i),
83 _ => None,
84 }
85 }
86
87 pub fn as_i64(&self) -> Option<i64> {
89 match self {
90 Value::Int64(i) => Some(*i),
91 Value::Int32(i) => Some(*i as i64),
92 _ => None,
93 }
94 }
95
96 pub fn as_f32(&self) -> Option<f32> {
98 match self {
99 Value::Float32(f) => Some(*f),
100 _ => None,
101 }
102 }
103
104 pub fn as_f64(&self) -> Option<f64> {
106 match self {
107 Value::Float64(f) => Some(*f),
108 Value::Float32(f) => Some(*f as f64),
109 _ => None,
110 }
111 }
112
113 pub fn as_str(&self) -> Option<&str> {
115 match self {
116 Value::String(s) => Some(s),
117 _ => None,
118 }
119 }
120
121 pub fn as_bytes(&self) -> Option<&[u8]> {
123 match self {
124 Value::Bytes(b) => Some(b),
125 _ => None,
126 }
127 }
128
129 pub fn as_timestamp(&self) -> Option<i64> {
131 match self {
132 Value::Timestamp(t) => Some(*t),
133 _ => None,
134 }
135 }
136
137 pub fn as_uuid(&self) -> Option<&[u8; 16]> {
139 match self {
140 Value::Uuid(u) => Some(u),
141 _ => None,
142 }
143 }
144}
145
146impl From<bool> for Value {
148 fn from(v: bool) -> Self {
149 Value::Bool(v)
150 }
151}
152
153impl From<i32> for Value {
154 fn from(v: i32) -> Self {
155 Value::Int32(v)
156 }
157}
158
159impl From<i64> for Value {
160 fn from(v: i64) -> Self {
161 Value::Int64(v)
162 }
163}
164
165impl From<f32> for Value {
166 fn from(v: f32) -> Self {
167 Value::Float32(v)
168 }
169}
170
171impl From<f64> for Value {
172 fn from(v: f64) -> Self {
173 Value::Float64(v)
174 }
175}
176
177impl From<String> for Value {
178 fn from(v: String) -> Self {
179 Value::String(v)
180 }
181}
182
183impl From<&str> for Value {
184 fn from(v: &str) -> Self {
185 Value::String(v.to_string())
186 }
187}
188
189impl From<Vec<u8>> for Value {
190 fn from(v: Vec<u8>) -> Self {
191 Value::Bytes(v)
192 }
193}
194
195impl From<[u8; 16]> for Value {
196 fn from(v: [u8; 16]) -> Self {
197 Value::Uuid(v)
198 }
199}
200
201impl From<Vec<bool>> for Value {
202 fn from(v: Vec<bool>) -> Self {
203 Value::BoolArray(v)
204 }
205}
206
207impl From<Vec<i32>> for Value {
208 fn from(v: Vec<i32>) -> Self {
209 Value::Int32Array(v)
210 }
211}
212
213impl From<Vec<i64>> for Value {
214 fn from(v: Vec<i64>) -> Self {
215 Value::Int64Array(v)
216 }
217}
218
219impl From<Vec<String>> for Value {
220 fn from(v: Vec<String>) -> Self {
221 Value::StringArray(v)
222 }
223}
224
225impl<T: Into<Value>> From<Option<T>> for Value {
226 fn from(v: Option<T>) -> Self {
227 match v {
228 Some(val) => val.into(),
229 None => Value::Null,
230 }
231 }
232}
233
234#[cfg(test)]
235mod tests {
236 use super::*;
237
238 #[test]
239 fn test_value_accessors() {
240 assert!(Value::Null.is_null());
241 assert!(!Value::Bool(true).is_null());
242
243 assert_eq!(Value::Bool(true).as_bool(), Some(true));
244 assert_eq!(Value::Int32(42).as_i32(), Some(42));
245 assert_eq!(Value::Int64(100).as_i64(), Some(100));
246 assert_eq!(Value::Int32(42).as_i64(), Some(42)); assert_eq!(Value::String("hello".into()).as_str(), Some("hello"));
249 assert_eq!(Value::Bytes(vec![1, 2, 3]).as_bytes(), Some(&[1, 2, 3][..]));
250 }
251
252 #[test]
253 fn test_value_conversions() {
254 let v: Value = true.into();
255 assert_eq!(v, Value::Bool(true));
256
257 let v: Value = 42i32.into();
258 assert_eq!(v, Value::Int32(42));
259
260 let v: Value = "hello".into();
261 assert_eq!(v, Value::String("hello".into()));
262
263 let v: Value = None::<i32>.into();
264 assert_eq!(v, Value::Null);
265
266 let v: Value = Some(42i32).into();
267 assert_eq!(v, Value::Int32(42));
268 }
269
270 #[test]
271 fn test_array_values() {
272 let v: Value = vec![1i32, 2, 3].into();
273 assert!(v.is_array());
274 assert_eq!(v, Value::Int32Array(vec![1, 2, 3]));
275
276 let v: Value = vec!["a".to_string(), "b".to_string()].into();
277 assert!(v.is_array());
278 }
279
280 #[test]
281 fn test_value_serialization_roundtrip() {
282 let values = vec![
283 Value::Null,
284 Value::Bool(true),
285 Value::Int32(-42),
286 Value::Int64(i64::MAX),
287 Value::Float32(3.14),
288 Value::Float64(std::f64::consts::PI),
289 Value::String("hello world".into()),
290 Value::Bytes(vec![0, 1, 2, 255]),
291 Value::Timestamp(1704067200_000_000), Value::Uuid([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
293 Value::Int32Array(vec![1, 2, 3]),
294 Value::StringArray(vec!["a".into(), "b".into()]),
295 ];
296
297 for value in values {
298 let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&value).unwrap();
299 let archived = rkyv::access::<ArchivedValue, rkyv::rancor::Error>(&bytes).unwrap();
300 let deserialized: Value =
301 rkyv::deserialize::<Value, rkyv::rancor::Error>(archived).unwrap();
302 assert_eq!(value, deserialized);
303 }
304 }
305}