ron/value/
mod.rs

1//! Value module.
2
3use std::{borrow::Cow, cmp::Eq, hash::Hash};
4
5use serde::{
6    de::{DeserializeOwned, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor},
7    forward_to_deserialize_any,
8};
9
10use crate::{de::Error, error::Result};
11
12mod map;
13mod number;
14pub(crate) mod raw;
15
16pub use map::Map;
17pub use number::{Number, F32, F64};
18#[allow(clippy::useless_attribute, clippy::module_name_repetitions)]
19pub use raw::RawValue;
20
21#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
22pub enum Value {
23    Bool(bool),
24    Char(char),
25    Map(Map),
26    Number(Number),
27    Option(Option<Box<Value>>),
28    String(String),
29    Bytes(Vec<u8>),
30    Seq(Vec<Value>),
31    Unit,
32}
33
34impl From<bool> for Value {
35    fn from(value: bool) -> Self {
36        Self::Bool(value)
37    }
38}
39
40impl From<char> for Value {
41    fn from(value: char) -> Self {
42        Self::Char(value)
43    }
44}
45
46impl<K: Into<Value>, V: Into<Value>> FromIterator<(K, V)> for Value {
47    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
48        Self::Map(iter.into_iter().collect())
49    }
50}
51
52impl From<Map> for Value {
53    fn from(value: Map) -> Self {
54        Self::Map(value)
55    }
56}
57
58impl<T: Into<Number>> From<T> for Value {
59    fn from(value: T) -> Self {
60        Self::Number(value.into())
61    }
62}
63
64impl<T: Into<Value>> From<Option<T>> for Value {
65    fn from(value: Option<T>) -> Self {
66        Self::Option(value.map(Into::into).map(Box::new))
67    }
68}
69
70impl<'a> From<&'a str> for Value {
71    fn from(value: &'a str) -> Self {
72        String::from(value).into()
73    }
74}
75
76impl<'a> From<Cow<'a, str>> for Value {
77    fn from(value: Cow<'a, str>) -> Self {
78        String::from(value).into()
79    }
80}
81
82impl From<String> for Value {
83    fn from(value: String) -> Self {
84        Self::String(value)
85    }
86}
87
88/// Special case to allow `Value::from(b"byte string")`
89impl<const N: usize> From<&'static [u8; N]> for Value {
90    fn from(value: &'static [u8; N]) -> Self {
91        Self::Bytes(Vec::from(*value))
92    }
93}
94
95impl<T: Into<Value>> FromIterator<T> for Value {
96    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
97        Self::Seq(iter.into_iter().map(Into::into).collect())
98    }
99}
100
101impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
102    fn from(value: &'a [T]) -> Self {
103        value.iter().map(Clone::clone).map(Into::into).collect()
104    }
105}
106
107impl<T: Into<Value>> From<Vec<T>> for Value {
108    fn from(value: Vec<T>) -> Self {
109        value.into_iter().collect()
110    }
111}
112
113impl From<()> for Value {
114    fn from(_value: ()) -> Self {
115        Value::Unit
116    }
117}
118
119impl Value {
120    /// Tries to deserialize this [`Value`] into `T`.
121    pub fn into_rust<T>(self) -> Result<T>
122    where
123        T: DeserializeOwned,
124    {
125        T::deserialize(self)
126    }
127}
128
129/// Deserializer implementation for RON [`Value`].
130/// This does not support enums (because [`Value`] does not store them).
131impl<'de> Deserializer<'de> for Value {
132    type Error = Error;
133
134    forward_to_deserialize_any! {
135        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
136        byte_buf option unit unit_struct newtype_struct seq tuple
137        tuple_struct map struct enum identifier ignored_any
138    }
139
140    #[cfg(feature = "integer128")]
141    forward_to_deserialize_any! {
142        i128 u128
143    }
144
145    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
146    where
147        V: Visitor<'de>,
148    {
149        match self {
150            Value::Bool(b) => visitor.visit_bool(b),
151            Value::Char(c) => visitor.visit_char(c),
152            Value::Map(m) => {
153                let old_len = m.len();
154
155                let mut items: Vec<(Value, Value)> = m.into_iter().collect();
156                items.reverse();
157
158                let value = visitor.visit_map(MapAccessor {
159                    items: &mut items,
160                    value: None,
161                })?;
162
163                if items.is_empty() {
164                    Ok(value)
165                } else {
166                    Err(Error::ExpectedDifferentLength {
167                        expected: format!("a map of length {}", old_len - items.len()),
168                        found: old_len,
169                    })
170                }
171            }
172            Value::Number(number) => number.visit(visitor),
173            Value::Option(Some(o)) => visitor.visit_some(*o),
174            Value::Option(None) => visitor.visit_none(),
175            Value::String(s) => visitor.visit_string(s),
176            Value::Bytes(b) => visitor.visit_byte_buf(b),
177            Value::Seq(mut seq) => {
178                let old_len = seq.len();
179
180                seq.reverse();
181                let value = visitor.visit_seq(SeqAccessor { seq: &mut seq })?;
182
183                if seq.is_empty() {
184                    Ok(value)
185                } else {
186                    Err(Error::ExpectedDifferentLength {
187                        expected: format!("a sequence of length {}", old_len - seq.len()),
188                        found: old_len,
189                    })
190                }
191            }
192            Value::Unit => visitor.visit_unit(),
193        }
194    }
195}
196
197struct SeqAccessor<'a> {
198    seq: &'a mut Vec<Value>,
199}
200
201impl<'a, 'de> SeqAccess<'de> for SeqAccessor<'a> {
202    type Error = Error;
203
204    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
205    where
206        T: DeserializeSeed<'de>,
207    {
208        // The `Vec` is reversed, so we can pop to get the originally first element
209        self.seq
210            .pop()
211            .map_or(Ok(None), |v| seed.deserialize(v).map(Some))
212    }
213
214    fn size_hint(&self) -> Option<usize> {
215        Some(self.seq.len())
216    }
217}
218
219struct MapAccessor<'a> {
220    items: &'a mut Vec<(Value, Value)>,
221    value: Option<Value>,
222}
223
224impl<'a, 'de> MapAccess<'de> for MapAccessor<'a> {
225    type Error = Error;
226
227    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
228    where
229        K: DeserializeSeed<'de>,
230    {
231        // The `Vec` is reversed, so we can pop to get the originally first element
232        match self.items.pop() {
233            Some((key, value)) => {
234                self.value = Some(value);
235                seed.deserialize(key).map(Some)
236            }
237            None => Ok(None),
238        }
239    }
240
241    #[allow(clippy::panic)]
242    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
243    where
244        V: DeserializeSeed<'de>,
245    {
246        match self.value.take() {
247            Some(value) => seed.deserialize(value),
248            None => panic!("Contract violation: value before key"),
249        }
250    }
251
252    fn size_hint(&self) -> Option<usize> {
253        Some(self.items.len())
254    }
255}
256
257#[cfg(test)]
258mod tests {
259    use std::{collections::BTreeMap, fmt::Debug};
260
261    use serde::Deserialize;
262
263    use super::*;
264
265    fn assert_same<'de, T>(s: &'de str)
266    where
267        T: Debug + Deserialize<'de> + PartialEq,
268    {
269        use crate::de::from_str;
270
271        let direct: T = from_str(s).unwrap();
272        let value: Value = from_str(s).unwrap();
273        let de = T::deserialize(value.clone()).unwrap();
274
275        assert_eq!(direct, de, "Deserialization for {:?} is not the same", s);
276
277        let value_roundtrip = Value::deserialize(value.clone()).unwrap();
278        assert_eq!(value_roundtrip, value);
279    }
280
281    fn assert_same_bytes<'de, T>(s: &'de [u8])
282    where
283        T: Debug + Deserialize<'de> + PartialEq,
284    {
285        use crate::de::from_bytes;
286
287        let direct: T = from_bytes(s).unwrap();
288        let value: Value = from_bytes(s).unwrap();
289        let de = T::deserialize(value.clone()).unwrap();
290
291        assert_eq!(direct, de, "Deserialization for {:?} is not the same", s);
292
293        let value_roundtrip = Value::deserialize(value.clone()).unwrap();
294        assert_eq!(value_roundtrip, value);
295    }
296
297    #[test]
298    fn boolean() {
299        assert_same::<bool>("true");
300        assert_same::<bool>("false");
301
302        assert_eq!(Value::from(true), Value::Bool(true));
303        assert_eq!(Value::from(false), Value::Bool(false));
304    }
305
306    #[test]
307    fn float() {
308        assert_same::<f64>("0.123");
309        assert_same::<f64>("-4.19");
310
311        assert_eq!(
312            Value::from(42_f32),
313            Value::Number(Number::F32(42_f32.into()))
314        );
315        assert_eq!(
316            Value::from(42_f64),
317            Value::Number(Number::F64(42_f64.into()))
318        );
319    }
320
321    #[test]
322    fn int() {
323        assert_same::<u32>("626");
324        assert_same::<i32>("-50");
325
326        assert_eq!(Value::from(0_i8), Value::Number(Number::I8(0)));
327        assert_eq!(Value::from(0_i16), Value::Number(Number::I16(0)));
328        assert_eq!(Value::from(0_i32), Value::Number(Number::I32(0)));
329        assert_eq!(Value::from(0_i64), Value::Number(Number::I64(0)));
330        #[cfg(feature = "integer128")]
331        assert_eq!(Value::from(0_i128), Value::Number(Number::I128(0)));
332        assert_eq!(Value::from(0_u8), Value::Number(Number::U8(0)));
333        assert_eq!(Value::from(0_u16), Value::Number(Number::U16(0)));
334        assert_eq!(Value::from(0_u32), Value::Number(Number::U32(0)));
335        assert_eq!(Value::from(0_u64), Value::Number(Number::U64(0)));
336        #[cfg(feature = "integer128")]
337        assert_eq!(Value::from(0_u128), Value::Number(Number::U128(0)));
338    }
339
340    #[test]
341    fn char() {
342        assert_same::<char>("'4'");
343        assert_same::<char>("'c'");
344
345        assert_eq!(Value::from('🦀'), Value::Char('🦀'));
346    }
347
348    #[test]
349    fn string() {
350        assert_same::<String>(r#""hello world""#);
351        assert_same::<String>(r#""this is a Rusty 🦀 string""#);
352        assert_same::<String>(r#""this is now valid UTF-8 \xf0\x9f\xa6\x80""#);
353
354        assert_eq!(Value::from("slice"), Value::String(String::from("slice")));
355        assert_eq!(
356            Value::from(String::from("string")),
357            Value::String(String::from("string"))
358        );
359        assert_eq!(
360            Value::from(Cow::Borrowed("cow")),
361            Value::String(String::from("cow"))
362        );
363    }
364
365    #[test]
366    fn bytes() {
367        assert_same_bytes::<serde_bytes::ByteBuf>(br#"b"hello world""#);
368        assert_same_bytes::<serde_bytes::ByteBuf>(
369            br#"b"this is not valid UTF-8 \xf8\xa1\xa1\xa1\xa1""#,
370        );
371
372        assert_eq!(Value::from(b"bytes"), Value::Bytes(Vec::from(*b"bytes")));
373    }
374
375    #[test]
376    fn map() {
377        assert_same::<BTreeMap<char, String>>(
378            "{
379'a': \"Hello\",
380'b': \"Bye\",
381        }",
382        );
383
384        assert_eq!(Value::from(Map::new()), Value::Map(Map::new()));
385        assert_eq!(
386            Value::from_iter([("a", 42)]),
387            Value::Map({
388                let mut map = Map::new();
389                map.insert(Value::from("a"), Value::from(42));
390                map
391            })
392        );
393    }
394
395    #[test]
396    fn option() {
397        assert_same::<Option<char>>("Some('a')");
398        assert_same::<Option<char>>("None");
399
400        assert_eq!(Value::from(Option::<bool>::None), Value::Option(None));
401        assert_eq!(
402            Value::from(Some(false)),
403            Value::Option(Some(Box::new(Value::Bool(false))))
404        );
405        assert_eq!(
406            Value::from(Some(Option::<bool>::None)),
407            Value::Option(Some(Box::new(Value::Option(None))))
408        );
409    }
410
411    #[test]
412    fn seq() {
413        assert_same::<Vec<f64>>("[1.0, 2.0, 3.0, 4.0]");
414
415        assert_eq!(
416            Value::from([-1_i8, 2, -3].as_slice()),
417            Value::Seq(vec![
418                Value::from(-1_i8),
419                Value::from(2_i8),
420                Value::from(-3_i8)
421            ])
422        );
423        assert_eq!(
424            Value::from(vec![-1_i8, 2, -3]),
425            Value::Seq(vec![
426                Value::from(-1_i8),
427                Value::from(2_i8),
428                Value::from(-3_i8)
429            ])
430        );
431        assert_eq!(
432            Value::from_iter([-1_i8, 2, -3]),
433            Value::Seq(vec![
434                Value::from(-1_i8),
435                Value::from(2_i8),
436                Value::from(-3_i8)
437            ])
438        );
439    }
440
441    #[test]
442    fn unit() {
443        assert_same::<()>("()");
444
445        assert_eq!(Value::from(()), Value::Unit);
446    }
447
448    #[test]
449    #[should_panic(expected = "Contract violation: value before key")]
450    fn map_access_contract_violation() {
451        struct BadVisitor;
452
453        impl<'de> Visitor<'de> for BadVisitor {
454            type Value = ();
455
456            // GRCOV_EXCL_START
457            fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
458                fmt.write_str("a map")
459            }
460            // GRCOV_EXCL_STOP
461
462            fn visit_map<A: serde::de::MapAccess<'de>>(
463                self,
464                mut map: A,
465            ) -> Result<Self::Value, A::Error> {
466                map.next_value::<()>()
467            }
468        }
469
470        let value = Value::Map([("a", 42)].into_iter().collect());
471        let _ = value.deserialize_map(BadVisitor);
472    }
473
474    #[test]
475    fn transparent_value_newtype() {
476        struct NewtypeDeserializer;
477
478        impl<'de> Deserializer<'de> for NewtypeDeserializer {
479            type Error = Error;
480
481            fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
482                visitor.visit_newtype_struct(serde::de::value::CharDeserializer::new('🦀'))
483            }
484
485            // GRCOV_EXCL_START
486            forward_to_deserialize_any! {
487                bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
488                bytes byte_buf option unit unit_struct newtype_struct seq tuple
489                tuple_struct map struct enum identifier ignored_any
490            }
491
492            #[cfg(feature = "integer128")]
493            forward_to_deserialize_any! { i128 u128 }
494            // GRCOV_EXCL_STOP
495        }
496
497        assert_eq!(
498            Value::deserialize(NewtypeDeserializer).unwrap(),
499            Value::from('🦀')
500        );
501    }
502}