serde_value/
lib.rs

1#![doc(html_root_url="https://docs.rs/serde-value/0.7.0/")]
2
3use std::collections::BTreeMap;
4use std::cmp::Ordering;
5use std::hash::{Hash, Hasher};
6use serde::Deserialize;
7use ordered_float::OrderedFloat;
8
9pub use de::*;
10pub use ser::*;
11
12mod de;
13mod ser;
14
15#[derive(Clone, Debug)]
16pub enum Value {
17    Bool(bool),
18
19    U8(u8),
20    U16(u16),
21    U32(u32),
22    U64(u64),
23
24    I8(i8),
25    I16(i16),
26    I32(i32),
27    I64(i64),
28
29    F32(f32),
30    F64(f64),
31
32    Char(char),
33    String(String),
34
35    Unit,
36    Option(Option<Box<Value>>),
37    Newtype(Box<Value>),
38    Seq(Vec<Value>),
39    Map(BTreeMap<Value, Value>),
40    Bytes(Vec<u8>),
41}
42
43impl Hash for Value {
44    fn hash<H>(&self, hasher: &mut H)
45    where
46        H: Hasher
47    {
48        self.discriminant().hash(hasher);
49        match *self {
50            Value::Bool(v) => v.hash(hasher),
51            Value::U8(v) => v.hash(hasher),
52            Value::U16(v) => v.hash(hasher),
53            Value::U32(v) => v.hash(hasher),
54            Value::U64(v) => v.hash(hasher),
55            Value::I8(v) => v.hash(hasher),
56            Value::I16(v) => v.hash(hasher),
57            Value::I32(v) => v.hash(hasher),
58            Value::I64(v) => v.hash(hasher),
59            Value::F32(v) => OrderedFloat(v).hash(hasher),
60            Value::F64(v) => OrderedFloat(v).hash(hasher),
61            Value::Char(v) => v.hash(hasher),
62            Value::String(ref v) => v.hash(hasher),
63            Value::Unit => ().hash(hasher),
64            Value::Option(ref v) => v.hash(hasher),
65            Value::Newtype(ref v) => v.hash(hasher),
66            Value::Seq(ref v) => v.hash(hasher),
67            Value::Map(ref v) => v.hash(hasher),
68            Value::Bytes(ref v) => v.hash(hasher),
69        }
70    }
71}
72
73impl PartialEq for Value {
74    fn eq(&self, rhs: &Self) -> bool {
75        match (self, rhs) {
76            (&Value::Bool(v0), &Value::Bool(v1)) if v0 == v1 => true,
77            (&Value::U8(v0), &Value::U8(v1)) if v0 == v1 => true,
78            (&Value::U16(v0), &Value::U16(v1)) if v0 == v1 => true,
79            (&Value::U32(v0), &Value::U32(v1)) if v0 == v1 => true,
80            (&Value::U64(v0), &Value::U64(v1)) if v0 == v1 => true,
81            (&Value::I8(v0), &Value::I8(v1)) if v0 == v1 => true,
82            (&Value::I16(v0), &Value::I16(v1)) if v0 == v1 => true,
83            (&Value::I32(v0), &Value::I32(v1)) if v0 == v1 => true,
84            (&Value::I64(v0), &Value::I64(v1)) if v0 == v1 => true,
85            (&Value::F32(v0), &Value::F32(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
86            (&Value::F64(v0), &Value::F64(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
87            (&Value::Char(v0), &Value::Char(v1)) if v0 == v1 => true,
88            (&Value::String(ref v0), &Value::String(ref v1)) if v0 == v1 => true,
89            (&Value::Unit, &Value::Unit) => true,
90            (&Value::Option(ref v0), &Value::Option(ref v1)) if v0 == v1 => true,
91            (&Value::Newtype(ref v0), &Value::Newtype(ref v1)) if v0 == v1 => true,
92            (&Value::Seq(ref v0), &Value::Seq(ref v1)) if v0 == v1 => true,
93            (&Value::Map(ref v0), &Value::Map(ref v1)) if v0 == v1 => true,
94            (&Value::Bytes(ref v0), &Value::Bytes(ref v1)) if v0 == v1 => true,
95            _ => false,
96        }
97    }
98}
99
100impl Ord for Value {
101    fn cmp(&self, rhs: &Self) -> Ordering {
102        match (self, rhs) {
103            (&Value::Bool(v0), &Value::Bool(ref v1)) => v0.cmp(v1),
104            (&Value::U8(v0), &Value::U8(ref v1)) => v0.cmp(v1),
105            (&Value::U16(v0), &Value::U16(ref v1)) => v0.cmp(v1),
106            (&Value::U32(v0), &Value::U32(ref v1)) => v0.cmp(v1),
107            (&Value::U64(v0), &Value::U64(ref v1)) => v0.cmp(v1),
108            (&Value::I8(v0), &Value::I8(ref v1)) => v0.cmp(v1),
109            (&Value::I16(v0), &Value::I16(ref v1)) => v0.cmp(v1),
110            (&Value::I32(v0), &Value::I32(ref v1)) => v0.cmp(v1),
111            (&Value::I64(v0), &Value::I64(ref v1)) => v0.cmp(v1),
112            (&Value::F32(v0), &Value::F32(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
113            (&Value::F64(v0), &Value::F64(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
114            (&Value::Char(v0), &Value::Char(ref v1)) => v0.cmp(v1),
115            (&Value::String(ref v0), &Value::String(ref v1)) => v0.cmp(v1),
116            (&Value::Unit, &Value::Unit) => Ordering::Equal,
117            (&Value::Option(ref v0), &Value::Option(ref v1)) => v0.cmp(v1),
118            (&Value::Newtype(ref v0), &Value::Newtype(ref v1)) => v0.cmp(v1),
119            (&Value::Seq(ref v0), &Value::Seq(ref v1)) => v0.cmp(v1),
120            (&Value::Map(ref v0), &Value::Map(ref v1)) => v0.cmp(v1),
121            (&Value::Bytes(ref v0), &Value::Bytes(ref v1)) => v0.cmp(v1),
122            (ref v0, ref v1) => v0.discriminant().cmp(&v1.discriminant()),
123        }
124    }
125}
126
127impl Value {
128    fn discriminant(&self) -> usize {
129        match *self {
130            Value::Bool(..) => 0,
131            Value::U8(..) => 1,
132            Value::U16(..) => 2,
133            Value::U32(..) => 3,
134            Value::U64(..) => 4,
135            Value::I8(..) => 5,
136            Value::I16(..) => 6,
137            Value::I32(..) => 7,
138            Value::I64(..) => 8,
139            Value::F32(..) => 9,
140            Value::F64(..) => 10,
141            Value::Char(..) => 11,
142            Value::String(..) => 12,
143            Value::Unit => 13,
144            Value::Option(..) => 14,
145            Value::Newtype(..) => 15,
146            Value::Seq(..) => 16,
147            Value::Map(..) => 17,
148            Value::Bytes(..) => 18,
149        }
150    }
151
152    fn unexpected(&self) -> serde::de::Unexpected {
153        match *self {
154            Value::Bool(b) => serde::de::Unexpected::Bool(b),
155            Value::U8(n) => serde::de::Unexpected::Unsigned(n as u64),
156            Value::U16(n) => serde::de::Unexpected::Unsigned(n as u64),
157            Value::U32(n) => serde::de::Unexpected::Unsigned(n as u64),
158            Value::U64(n) => serde::de::Unexpected::Unsigned(n),
159            Value::I8(n) => serde::de::Unexpected::Signed(n as i64),
160            Value::I16(n) => serde::de::Unexpected::Signed(n as i64),
161            Value::I32(n) => serde::de::Unexpected::Signed(n as i64),
162            Value::I64(n) => serde::de::Unexpected::Signed(n),
163            Value::F32(n) => serde::de::Unexpected::Float(n as f64),
164            Value::F64(n) => serde::de::Unexpected::Float(n),
165            Value::Char(c) => serde::de::Unexpected::Char(c),
166            Value::String(ref s) => serde::de::Unexpected::Str(s),
167            Value::Unit => serde::de::Unexpected::Unit,
168            Value::Option(_) => serde::de::Unexpected::Option,
169            Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
170            Value::Seq(_) => serde::de::Unexpected::Seq,
171            Value::Map(_) => serde::de::Unexpected::Map,
172            Value::Bytes(ref b) => serde::de::Unexpected::Bytes(b),
173        }
174    }
175
176    pub fn deserialize_into<'de, T: Deserialize<'de>>(self) -> Result<T, DeserializerError> {
177        T::deserialize(self)
178    }
179}
180
181impl Eq for Value { }
182impl PartialOrd for Value {
183    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
184        Some(self.cmp(rhs))
185    }
186}
187
188#[cfg(test)]
189use serde_derive::{Deserialize, Serialize};
190
191#[test]
192fn de_smoke_test() {
193    // some convoluted Value
194    let value = Value::Option(Some(Box::new(Value::Seq(vec![
195        Value::U16(8),
196        Value::Char('a'),
197        Value::F32(1.0),
198        Value::String("hello".into()),
199        Value::Map(vec![
200            (Value::Bool(false), Value::Unit),
201            (Value::Bool(true), Value::Newtype(Box::new(
202                Value::Bytes(b"hi".as_ref().into())
203            ))),
204        ].into_iter().collect()),
205    ]))));
206
207    // assert that the value remains unchanged through deserialization
208    let value_de = Value::deserialize(value.clone()).unwrap();
209    assert_eq!(value_de, value);
210}
211
212#[test]
213fn ser_smoke_test() {
214    #[derive(Serialize)]
215    struct Foo {
216        a: u32,
217        b: String,
218        c: Vec<bool>,
219    }
220
221    let foo = Foo {
222        a: 15,
223        b: "hello".into(),
224        c: vec![true, false],
225    };
226
227    let expected = Value::Map(vec![
228        (Value::String("a".into()), Value::U32(15)),
229        (Value::String("b".into()), Value::String("hello".into())),
230        (Value::String("c".into()), Value::Seq(vec![Value::Bool(true), Value::Bool(false)])),
231    ].into_iter().collect());
232
233    let value = to_value(&foo).unwrap();
234    assert_eq!(expected, value);
235}
236
237#[test]
238fn deserialize_into_enum() {
239    #[derive(Deserialize, Debug, PartialEq, Eq)]
240    enum Foo {
241        Bar,
242        Baz(u8),
243    }
244
245    let value = Value::String("Bar".into());
246    assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
247
248    let value = Value::Map(vec![
249        (Value::String("Baz".into()), Value::U8(1))
250    ].into_iter().collect());
251    assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
252}
253
254#[test]
255fn serialize_from_enum() {
256    #[derive(Serialize)]
257    enum Foo {
258        Bar,
259        Baz(u8),
260        Qux { quux: u8 },
261        Corge(u8, u8),
262    }
263
264    let bar = Foo::Bar;
265    assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
266
267    let baz = Foo::Baz(1);
268    assert_eq!(
269        to_value(&baz).unwrap(),
270        Value::Map(
271            vec![(Value::String("Baz".into()), Value::U8(1))]
272                .into_iter()
273                .collect(),
274        )
275    );
276
277    let qux = Foo::Qux { quux: 2 };
278    assert_eq!(
279        to_value(&qux).unwrap(),
280        Value::Map(
281            vec![(
282                Value::String("Qux".into()),
283                Value::Map(
284                    vec![(Value::String("quux".into()), Value::U8(2))]
285                        .into_iter()
286                        .collect()
287                )
288            )]
289            .into_iter()
290            .collect()
291        )
292    );
293
294    let corge = Foo::Corge(3, 4);
295    assert_eq!(
296        to_value(&corge).unwrap(),
297        Value::Map(
298            vec![(
299                Value::String("Corge".into()),
300                Value::Seq(vec![Value::U8(3), Value::U8(4)])
301            )]
302            .into_iter()
303            .collect()
304        )
305    );
306}
307
308#[test]
309fn deserialize_inside_deserialize_impl() {
310    #[derive(Debug, PartialEq, Eq)]
311    enum Event {
312        Added(u32),
313        Error(u8),
314    }
315
316    impl<'de> serde::Deserialize<'de> for Event {
317        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de> {
318            #[derive(Deserialize)]
319            struct RawEvent {
320                kind: String,
321                object: Value,
322            }
323
324            let raw_event = RawEvent::deserialize(deserializer)?;
325
326            // Cannot directly use Value as Deserializer, since error type needs to be
327            // generic D::Error rather than specific serde_value::DeserializerError
328            let object_deserializer = ValueDeserializer::new(raw_event.object);
329
330            Ok(match &*raw_event.kind {
331                "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
332                "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
333                kind => return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"])),
334            })
335        }
336    }
337
338    let input = Value::Map(vec![
339        (Value::String("kind".to_owned()), Value::String("ADDED".to_owned())),
340        (Value::String("object".to_owned()), Value::U32(5)),
341    ].into_iter().collect());
342    let event = Event::deserialize(input).expect("could not deserialize ADDED event");
343    assert_eq!(event, Event::Added(5));
344
345    let input = Value::Map(vec![
346        (Value::String("kind".to_owned()), Value::String("ERROR".to_owned())),
347        (Value::String("object".to_owned()), Value::U8(5)),
348    ].into_iter().collect());
349    let event = Event::deserialize(input).expect("could not deserialize ERROR event");
350    assert_eq!(event, Event::Error(5));
351
352    let input = Value::Map(vec![
353        (Value::String("kind".to_owned()), Value::String("ADDED".to_owned())),
354        (Value::String("object".to_owned()), Value::Unit),
355    ].into_iter().collect());
356    let _ = Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
357}
358
359#[test]
360fn deserialize_newtype() {
361    #[derive(Debug, Deserialize, PartialEq)]
362    struct Foo(i32);
363
364    let input = Value::I32(5);
365    let foo = Foo::deserialize(input).unwrap();
366    assert_eq!(foo, Foo(5));
367}
368
369#[test]
370fn deserialize_newtype2() {
371    #[derive(Debug, Deserialize, PartialEq)]
372    struct Foo(i32);
373
374    #[derive(Debug, Deserialize, PartialEq)]
375    struct Bar {
376        foo: Foo,
377    }
378
379    let input = Value::Map(vec![
380        (Value::String("foo".to_owned()), Value::I32(5))
381    ].into_iter().collect());
382    let bar = Bar::deserialize(input).unwrap();
383    assert_eq!(bar, Bar { foo: Foo(5) });
384}