Skip to main content

ron/value/
mod.rs

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