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