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