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