1use std::collections::BTreeMap;
2use std::fmt::Debug;
3use std::{fmt, str};
4
5use serde::de::{Deserialize, MapAccess, SeqAccess, Visitor};
6use serde::ser::{Serialize, SerializeMap, SerializeSeq, Serializer};
7use uuid::Uuid;
8
9use crate::FiniteF64;
10use crate::annotated::Annotated;
11use crate::meta::Meta;
12
13pub type Array<T> = Vec<Annotated<T>>;
15
16pub type Map<K, T> = BTreeMap<K, T>;
18
19pub type Object<T> = Map<String, Annotated<T>>;
21
22#[derive(Debug, Clone, PartialEq)]
24pub enum Value {
25 Bool(bool),
27 I64(i64),
29 U64(u64),
31 F64(f64),
33 String(String),
35 Array(Array<Value>),
37 Object(Object<Value>),
39}
40
41pub struct ValueDescription<'a>(&'a Value);
43
44impl fmt::Display for ValueDescription<'_> {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match *self.0 {
47 Value::Bool(true) => f.pad("true"),
48 Value::Bool(false) => f.pad("false"),
49 Value::I64(val) => write!(f, "integer {val}"),
50 Value::U64(val) => write!(f, "integer {val}"),
51 Value::F64(val) => write!(f, "float {val}"),
52 Value::String(ref val) => f.pad(val),
53 Value::Array(_) => f.pad("an array"),
54 Value::Object(_) => f.pad("an object"),
55 }
56 }
57}
58
59impl Value {
60 pub fn describe(&self) -> ValueDescription<'_> {
62 ValueDescription(self)
63 }
64
65 pub fn as_str(&self) -> Option<&str> {
67 match self {
68 Value::String(string) => Some(string.as_str()),
69 _ => None,
70 }
71 }
72
73 pub fn into_string(self) -> Option<String> {
75 match self {
76 Value::String(string) => Some(string),
77 _ => None,
78 }
79 }
80
81 pub fn as_f64(&self) -> Option<f64> {
83 match self {
84 Value::F64(f) => Some(*f),
85 Value::I64(i) => Some(*i as f64),
86 Value::U64(u) => Some(*u as f64),
87 _ => None,
88 }
89 }
90
91 fn from_json(value: serde_json::Value) -> Option<Self> {
93 Some(match value {
94 serde_json::Value::Null => return None,
95 serde_json::Value::Bool(value) => Value::Bool(value),
96 serde_json::Value::Number(num) => {
97 if let Some(val) = num.as_i64() {
98 Value::I64(val)
99 } else if let Some(val) = num.as_u64() {
100 Value::U64(val)
101 } else if let Some(val) = num.as_f64() {
102 Value::F64(val)
103 } else {
104 unreachable!()
107 }
108 }
109 serde_json::Value::String(val) => Value::String(val),
110 serde_json::Value::Array(items) => {
111 Value::Array(items.into_iter().map(Annotated::<Value>::from).collect())
112 }
113 serde_json::Value::Object(items) => Value::Object(
114 items
115 .into_iter()
116 .map(|(k, v)| (k, Annotated::<Value>::from(v)))
117 .collect(),
118 ),
119 })
120 }
121}
122
123impl TryFrom<&Value> for String {
124 type Error = ();
125
126 fn try_from(value: &Value) -> Result<Self, Self::Error> {
127 Ok(match value {
128 Value::Bool(v) => v.to_string(),
129 Value::I64(v) => v.to_string(),
130 Value::U64(v) => v.to_string(),
131 Value::F64(v) => v.to_string(),
132 Value::String(v) => v.to_string(),
133 _ => return Err(()),
134 })
135 }
136}
137
138impl Serialize for Value {
139 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
140 where
141 S: Serializer,
142 {
143 match *self {
144 Value::Bool(val) => serializer.serialize_bool(val),
145 Value::I64(val) => serializer.serialize_i64(val),
146 Value::U64(val) => serializer.serialize_u64(val),
147 Value::F64(val) => serializer.serialize_f64(val),
148 Value::String(ref val) => serializer.serialize_str(val),
149 Value::Array(ref items) => {
150 let mut seq_ser = serializer.serialize_seq(Some(items.len()))?;
151 for item in items {
152 match item {
153 Annotated(Some(val), _) => seq_ser.serialize_element(val)?,
154 Annotated(None, _) => seq_ser.serialize_element(&())?,
155 }
156 }
157 seq_ser.end()
158 }
159 Value::Object(ref items) => {
160 let mut map_ser = serializer.serialize_map(Some(items.len()))?;
161 for (key, value) in items {
162 map_ser.serialize_key(key)?;
163 match value {
164 Annotated(Some(val), _) => map_ser.serialize_value(val)?,
165 Annotated(None, _) => map_ser.serialize_value(&())?,
166 }
167 }
168 map_ser.end()
169 }
170 }
171 }
172}
173
174impl From<serde_json::Value> for Annotated<Value> {
175 fn from(value: serde_json::Value) -> Annotated<Value> {
176 Annotated::from(Value::from_json(value))
177 }
178}
179
180impl From<Value> for serde_json::Value {
181 fn from(value: Value) -> serde_json::Value {
182 match value {
183 Value::Bool(value) => serde_json::Value::Bool(value),
184 Value::I64(value) => serde_json::Value::Number(value.into()),
185 Value::U64(value) => serde_json::Value::Number(value.into()),
186 Value::F64(value) => serde_json::Number::from_f64(value)
187 .map(serde_json::Value::Number)
188 .unwrap_or(serde_json::Value::Null),
189 Value::String(val) => serde_json::Value::String(val),
190 Value::Array(items) => {
191 serde_json::Value::Array(items.into_iter().map(serde_json::Value::from).collect())
192 }
193 Value::Object(items) => serde_json::Value::Object(
194 items
195 .into_iter()
196 .map(|(k, v)| (k, serde_json::Value::from(v)))
197 .collect(),
198 ),
199 }
200 }
201}
202
203impl From<Annotated<Value>> for serde_json::Value {
204 fn from(value: Annotated<Value>) -> serde_json::Value {
205 value
206 .0
207 .map(serde_json::Value::from)
208 .unwrap_or(serde_json::Value::Null)
209 }
210}
211
212impl From<bool> for Value {
213 fn from(value: bool) -> Self {
214 Value::Bool(value)
215 }
216}
217
218impl From<i64> for Value {
219 fn from(value: i64) -> Self {
220 Value::I64(value)
221 }
222}
223
224impl From<u64> for Value {
225 fn from(value: u64) -> Self {
226 Value::U64(value)
227 }
228}
229
230impl From<f64> for Value {
231 fn from(value: f64) -> Self {
232 Value::F64(value)
233 }
234}
235
236impl<'a> From<&'a str> for Value {
237 fn from(value: &'a str) -> Self {
238 Value::String(value.to_owned())
239 }
240}
241
242impl From<String> for Value {
243 fn from(value: String) -> Self {
244 Value::String(value)
245 }
246}
247
248impl From<Array<Value>> for Value {
249 fn from(value: Array<Value>) -> Self {
250 Value::Array(value)
251 }
252}
253
254impl From<Object<Value>> for Value {
255 fn from(value: Object<Value>) -> Self {
256 Value::Object(value)
257 }
258}
259
260impl<'de> Deserialize<'de> for Value {
261 #[inline]
262 fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
263 where
264 D: serde::Deserializer<'de>,
265 {
266 struct ValueVisitor;
267
268 impl<'de> Visitor<'de> for ValueVisitor {
269 type Value = Value;
270
271 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
272 formatter.write_str("any valid JSON value")
273 }
274
275 #[inline]
276 fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
277 Ok(Value::Bool(value))
278 }
279
280 #[inline]
281 fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
282 Ok(Value::I64(value))
283 }
284
285 #[inline]
286 fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
287 Ok(value
288 .try_into()
289 .map(Value::I64)
290 .unwrap_or(Value::U64(value)))
291 }
292
293 #[inline]
294 fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
295 Ok(Value::F64(value))
296 }
297
298 #[inline]
299 fn visit_str<E>(self, value: &str) -> Result<Value, E>
300 where
301 E: serde::de::Error,
302 {
303 self.visit_string(String::from(value))
304 }
305
306 #[inline]
307 fn visit_string<E>(self, value: String) -> Result<Value, E> {
308 Ok(Value::String(value))
309 }
310
311 #[inline]
312 fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
313 where
314 D: serde::Deserializer<'de>,
315 {
316 Deserialize::deserialize(deserializer)
317 }
318
319 #[inline]
320 fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
321 where
322 V: SeqAccess<'de>,
323 {
324 let mut vec = Vec::new();
325 while let Some(elem) = visitor.next_element()? {
326 vec.push(Annotated(elem, Meta::default()));
327 }
328 Ok(Value::Array(vec))
329 }
330
331 fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
332 where
333 V: MapAccess<'de>,
334 {
335 let mut values = Map::new();
336 while let Some((key, value)) = visitor.next_entry()? {
337 values.insert(key, Annotated(value, Meta::default()));
338 }
339 Ok(Value::Object(values))
340 }
341 }
342
343 deserializer.deserialize_any(ValueVisitor)
344 }
345}
346
347pub fn to_value<T>(value: &T) -> Result<Option<Value>, serde_json::Error>
349where
350 T: Serialize,
351{
352 serde_json::to_value(value).map(Value::from_json)
353}
354
355#[derive(Debug, Clone, Copy)]
357pub struct Arr<'a> {
358 _phantom: std::marker::PhantomData<&'a ()>,
359}
360
361#[derive(Debug, Clone, Copy)]
363pub struct Obj<'a> {
364 _phantom: std::marker::PhantomData<&'a ()>,
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq)]
370pub struct HexId<'a>(pub &'a [u8]);
371
372impl HexId<'_> {
373 pub fn match_str(&self, other: &str) -> bool {
376 if other.len() != 2 * self.0.len() {
377 return false;
378 }
379
380 let sx = (0..)
381 .step_by(2)
382 .map_while(|r| other.get(r..r + 2))
383 .map(|x| u8::from_str_radix(x, 16).ok());
384
385 self.0.iter().copied().map(Some).eq(sx)
386 }
387}
388
389#[derive(Debug, Clone, Copy)]
391pub enum Val<'a> {
392 Bool(bool),
394 I64(i64),
396 U64(u64),
398 F64(f64),
400 String(&'a str),
402 HexId(HexId<'a>),
404 Array(Arr<'a>),
406 Object(Obj<'a>),
408}
409
410impl<'a> Val<'a> {
411 pub fn as_bool(&self) -> Option<bool> {
413 match self {
414 Self::Bool(value) => Some(*value),
415 _ => None,
416 }
417 }
418
419 pub fn as_i64(&self) -> Option<i64> {
421 match self {
422 Self::I64(value) => Some(*value),
423 Self::U64(value) => (*value).try_into().ok(),
424 _ => None,
425 }
426 }
427
428 pub fn as_u64(&self) -> Option<u64> {
430 match self {
431 Self::I64(value) => (*value).try_into().ok(),
432 Self::U64(value) => Some(*value),
433 _ => None,
434 }
435 }
436
437 pub fn as_f64(&self) -> Option<f64> {
439 match self {
440 Self::I64(value) => Some(*value as f64),
441 Self::U64(value) => Some(*value as f64),
442 Self::F64(value) => Some(*value),
443 _ => None,
444 }
445 }
446
447 pub fn as_str(&self) -> Option<&'a str> {
449 match self {
450 Self::String(value) => Some(value),
451
452 _ => None,
453 }
454 }
455
456 pub fn as_hex_id(&self) -> Option<HexId<'_>> {
458 match self {
459 Self::HexId(value) => Some(*value),
460
461 _ => None,
462 }
463 }
464}
465
466impl From<bool> for Val<'_> {
467 fn from(value: bool) -> Self {
468 Self::Bool(value)
469 }
470}
471
472impl From<i64> for Val<'_> {
473 fn from(value: i64) -> Self {
474 Self::I64(value)
475 }
476}
477
478impl From<u64> for Val<'_> {
479 fn from(value: u64) -> Self {
480 Self::U64(value)
481 }
482}
483
484impl From<f64> for Val<'_> {
485 fn from(value: f64) -> Self {
486 Self::F64(value)
487 }
488}
489
490impl From<FiniteF64> for Val<'_> {
491 fn from(value: FiniteF64) -> Self {
492 Self::F64(value.to_f64())
493 }
494}
495
496impl<'a> From<&'a str> for Val<'a> {
497 fn from(value: &'a str) -> Self {
498 Self::String(value)
499 }
500}
501
502impl<'a> From<&'a Uuid> for Val<'a> {
503 fn from(value: &'a Uuid) -> Self {
504 Self::HexId(HexId(value.as_bytes()))
505 }
506}
507
508impl<'a, T> From<&'a T> for Val<'a>
509where
510 Val<'a>: From<T>,
511 T: Copy,
512{
513 fn from(value: &'a T) -> Self {
514 (*value).into()
515 }
516}
517
518impl<'a> From<&'a Value> for Val<'a> {
519 fn from(value: &'a Value) -> Self {
520 match value {
521 Value::Bool(value) => Self::Bool(*value),
522 Value::I64(value) => Self::I64(*value),
523 Value::U64(value) => Self::U64(*value),
524 Value::F64(value) => Self::F64(*value),
525 Value::String(value) => Self::String(value),
526 Value::Array(_) => Self::Array(Arr {
527 _phantom: Default::default(),
528 }),
529 Value::Object(_) => Self::Object(Obj {
530 _phantom: Default::default(),
531 }),
532 }
533 }
534}
535
536impl PartialEq for Val<'_> {
537 fn eq(&self, other: &Self) -> bool {
538 match (self, other) {
539 (Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
540 (Self::I64(l0), Self::I64(r0)) => l0 == r0,
541 (Self::I64(l0), Self::U64(r0)) => Ok(*l0) == (*r0).try_into(),
542 (Self::U64(l0), Self::U64(r0)) => l0 == r0,
543 (Self::U64(l0), Self::I64(r0)) => Ok(*l0) == (*r0).try_into(),
544 (Self::F64(l0), Self::F64(r0)) => l0 == r0,
545 (Self::String(l0), Self::String(r0)) => l0 == r0,
546 (Self::HexId(l0), Self::HexId(r0)) => l0 == r0,
547 (Self::Array(_), Self::Array(_)) => false,
548 (Self::Object(_), Self::Object(_)) => false,
549 _ => false,
550 }
551 }
552}
553
554#[cfg(test)]
555mod tests {
556 use super::*;
557
558 #[test]
559 fn test_unsigned_signed() {
560 let v: Value = serde_json::from_str("9223372036854775816").unwrap();
561 assert_eq!(v, Value::U64(9223372036854775816));
562
563 let v: Value = serde_json::from_str("123").unwrap();
564 assert_eq!(v, Value::I64(123));
565 }
566
567 #[test]
568 fn test_hex_id_comparison() {
569 let id = HexId(&[0xde, 0xad, 0xbe, 0xef]);
570 assert!(id.match_str("deadbeef"));
571 assert!(id.match_str("DEADBEEF"));
573 assert!(!id.match_str("deedbeef"));
575 assert!(!id.match_str("deadbee"));
577 assert!(!id.match_str("deadbeeff"));
579 assert!(!id.match_str("deadbeer"));
581 }
582}