1mod de;
4mod ser;
5
6use std::cmp::{Ord, Ordering, PartialOrd};
7use std::collections::BTreeMap;
8
9#[doc(inline)]
10pub use self::de::from_value;
11#[doc(inline)]
12pub use self::ser::to_value;
13
14#[derive(Clone, Debug)]
23pub enum Value {
24 Null,
26 Bool(bool),
28 Integer(i128),
35 Float(f64),
37 Bytes(Vec<u8>),
39 Text(String),
41 Array(Vec<Self>),
43 Map(BTreeMap<Self, Self>),
54 Tag(u64, Box<Self>),
56 #[doc(hidden)]
59 __Hidden,
60}
61
62impl PartialEq for Value {
63 fn eq(&self, other: &Self) -> bool {
64 self.cmp(other) == Ordering::Equal
65 }
66}
67
68impl Eq for Value {}
69
70impl PartialOrd for Value {
71 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
72 Some(self.cmp(other))
73 }
74}
75
76impl Ord for Value {
77 fn cmp(&self, other: &Self) -> Ordering {
78 use self::Value::{Array, Bytes, Integer, Map, Text};
85 if self.major_type() != other.major_type() {
86 return self.major_type().cmp(&other.major_type());
87 }
88 match (self, other) {
89 (Integer(a), Integer(b)) => a.abs().cmp(&b.abs()),
90 (Bytes(a), Bytes(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
91 (Text(a), Text(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
92 (Array(a), Array(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
93 (Map(a), Map(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
94 (Bytes(a), Bytes(b)) => a.cmp(b),
95 (Text(a), Text(b)) => a.cmp(b),
96 (a, b) => {
97 let a = crate::to_vec(a).expect("self is serializable");
98 let b = crate::to_vec(b).expect("other is serializable");
99 a.cmp(&b)
100 }
101 }
102 }
103}
104
105macro_rules! impl_from {
106 ($variant:path, $for_type:ty) => {
107 impl From<$for_type> for Value {
108 fn from(v: $for_type) -> Value {
109 $variant(v.into())
110 }
111 }
112 };
113}
114
115impl_from!(Value::Bool, bool);
116impl_from!(Value::Integer, i8);
117impl_from!(Value::Integer, i16);
118impl_from!(Value::Integer, i32);
119impl_from!(Value::Integer, i64);
120impl_from!(Value::Integer, u8);
122impl_from!(Value::Integer, u16);
123impl_from!(Value::Integer, u32);
124impl_from!(Value::Integer, u64);
125impl_from!(Value::Float, f32);
127impl_from!(Value::Float, f64);
128impl_from!(Value::Bytes, Vec<u8>);
129impl_from!(Value::Text, String);
130impl_from!(Value::Array, Vec<Value>);
132impl_from!(Value::Map, BTreeMap<Value, Value>);
133
134impl Value {
135 fn major_type(&self) -> u8 {
136 use self::Value::{__Hidden, Array, Bool, Bytes, Float, Integer, Map, Null, Tag, Text};
137 match self {
138 Null => 7,
139 Bool(_) => 7,
140 Integer(v) => u8::from(*v < 0),
141 Tag(_, _) => 6,
142 Float(_) => 7,
143 Bytes(_) => 2,
144 Text(_) => 3,
145 Array(_) => 4,
146 Map(_) => 5,
147 __Hidden => unreachable!(),
148 }
149 }
150}