Skip to main content

ron/de/
value.rs

1use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
2use core::fmt;
3
4use serde::{
5    de::{Error, MapAccess, SeqAccess, Visitor},
6    Deserialize, Deserializer,
7};
8
9use crate::{
10    error::SpannedResult,
11    value::{Map, Number, Value},
12};
13
14impl core::str::FromStr for Value {
15    type Err = crate::error::SpannedError;
16
17    /// Creates a value from a string reference.
18    fn from_str(s: &str) -> SpannedResult<Self> {
19        let mut de = super::Deserializer::from_str(s)?;
20
21        let val = Value::deserialize(&mut de).map_err(|e| de.span_error(e))?;
22        de.end().map_err(|e| de.span_error(e))?;
23
24        Ok(val)
25    }
26}
27
28impl<'de> Deserialize<'de> for Value {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: Deserializer<'de>,
32    {
33        deserializer.deserialize_any(ValueVisitor)
34    }
35}
36
37struct ValueVisitor;
38
39impl<'de> Visitor<'de> for ValueVisitor {
40    type Value = Value;
41
42    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        write!(f, "a RON value")
44    }
45
46    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
47    where
48        E: Error,
49    {
50        Ok(Value::Bool(v))
51    }
52
53    fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
54    where
55        E: Error,
56    {
57        Ok(Value::Number(Number::new(v)))
58    }
59
60    fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
61    where
62        E: Error,
63    {
64        Ok(Value::Number(Number::new(v)))
65    }
66
67    fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
68    where
69        E: Error,
70    {
71        Ok(Value::Number(Number::new(v)))
72    }
73
74    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
75    where
76        E: Error,
77    {
78        Ok(Value::Number(Number::new(v)))
79    }
80
81    #[cfg(feature = "integer128")]
82    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
83    where
84        E: Error,
85    {
86        Ok(Value::Number(Number::new(v)))
87    }
88
89    fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
90    where
91        E: Error,
92    {
93        Ok(Value::Number(Number::new(v)))
94    }
95
96    fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
97    where
98        E: Error,
99    {
100        Ok(Value::Number(Number::new(v)))
101    }
102
103    fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
104    where
105        E: Error,
106    {
107        Ok(Value::Number(Number::new(v)))
108    }
109
110    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
111    where
112        E: Error,
113    {
114        Ok(Value::Number(Number::new(v)))
115    }
116
117    #[cfg(feature = "integer128")]
118    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
119    where
120        E: Error,
121    {
122        Ok(Value::Number(Number::new(v)))
123    }
124
125    fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
126    where
127        E: Error,
128    {
129        Ok(Value::Number(Number::new(v)))
130    }
131
132    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
133    where
134        E: Error,
135    {
136        Ok(Value::Number(Number::new(v)))
137    }
138
139    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
140    where
141        E: Error,
142    {
143        Ok(Value::Char(v))
144    }
145
146    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
147    where
148        E: Error,
149    {
150        self.visit_string(v.to_owned())
151    }
152
153    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
154    where
155        E: Error,
156    {
157        Ok(Value::String(v))
158    }
159
160    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
161    where
162        E: Error,
163    {
164        self.visit_byte_buf(v.to_vec())
165    }
166
167    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
168    where
169        E: Error,
170    {
171        Ok(Value::Bytes(v))
172    }
173
174    fn visit_none<E>(self) -> Result<Self::Value, E>
175    where
176        E: Error,
177    {
178        Ok(Value::Option(None))
179    }
180
181    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
182    where
183        D: Deserializer<'de>,
184    {
185        Ok(Value::Option(Some(Box::new(
186            deserializer.deserialize_any(ValueVisitor)?,
187        ))))
188    }
189
190    fn visit_unit<E>(self) -> Result<Self::Value, E>
191    where
192        E: Error,
193    {
194        Ok(Value::Unit)
195    }
196
197    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
198    where
199        D: Deserializer<'de>,
200    {
201        deserializer.deserialize_any(ValueVisitor)
202    }
203
204    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
205    where
206        A: SeqAccess<'de>,
207    {
208        let mut vec = Vec::new();
209        if let Some(cap) = seq.size_hint() {
210            vec.reserve_exact(cautious_size_hint::<Value>(cap));
211        }
212
213        while let Some(x) = seq.next_element()? {
214            vec.push(x);
215        }
216
217        Ok(Value::Seq(vec))
218    }
219
220    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
221    where
222        A: MapAccess<'de>,
223    {
224        let mut res: Map = Map::new();
225
226        #[cfg(feature = "indexmap")]
227        if let Some(cap) = map.size_hint() {
228            res.0
229                .reserve_exact(cautious_size_hint::<(Value, Value)>(cap));
230        }
231
232        while let Some(entry) = map.next_entry::<Value, Value>()? {
233            res.insert(entry.0, entry.1);
234        }
235
236        Ok(Value::Map(res))
237    }
238}
239
240/// Caps a size hint to at most 1 MiB of preallocation, like serde's own
241/// collection impls, since other formats read it from untrusted input
242fn cautious_size_hint<T>(hint: usize) -> usize {
243    const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
244
245    match core::mem::size_of::<T>() {
246        0 => 0,
247        size => hint.min(MAX_PREALLOC_BYTES / size),
248    }
249}
250
251#[cfg(test)]
252mod tests {
253    use alloc::vec;
254    use core::str::FromStr;
255
256    use super::*;
257
258    fn eval(s: &str) -> Value {
259        s.parse().expect("Failed to parse")
260    }
261
262    #[test]
263    fn test_none() {
264        assert_eq!(eval("None"), Value::Option(None));
265    }
266
267    #[test]
268    fn test_some() {
269        assert_eq!(eval("Some(())"), Value::Option(Some(Box::new(Value::Unit))));
270        assert_eq!(
271            eval("Some  (  () )"),
272            Value::Option(Some(Box::new(Value::Unit)))
273        );
274    }
275
276    #[test]
277    fn test_tuples_basic() {
278        assert_eq!(
279            eval("(3, 4.0, 5.0)"),
280            Value::Seq(vec![
281                Value::Number(Number::U8(3)),
282                Value::Number(Number::F32(4.0.into())),
283                Value::Number(Number::F32(5.0.into())),
284            ],),
285        );
286    }
287
288    #[test]
289    fn test_tuples_ident() {
290        assert_eq!(
291            eval("(true, 3, 4, 5.0)"),
292            Value::Seq(vec![
293                Value::Bool(true),
294                Value::Number(Number::U8(3)),
295                Value::Number(Number::U8(4)),
296                Value::Number(Number::F32(5.0.into())),
297            ]),
298        );
299    }
300
301    #[test]
302    fn test_tuples_error() {
303        use crate::de::{Error, Position, Span, SpannedError};
304
305        assert_eq!(
306            Value::from_str("Foo:").unwrap_err(),
307            SpannedError {
308                code: Error::TrailingCharacters,
309                span: Span {
310                    start: Position { line: 1, col: 4 },
311                    end: Position { line: 1, col: 4 }
312                }
313            },
314        );
315    }
316
317    #[test]
318    fn test_floats() {
319        assert_eq!(
320            eval("(inf, -inf, NaN)"),
321            Value::Seq(vec![
322                Value::Number(Number::new(core::f32::INFINITY)),
323                Value::Number(Number::new(core::f32::NEG_INFINITY)),
324                Value::Number(Number::new(core::f32::NAN)),
325            ]),
326        );
327    }
328
329    #[test]
330    fn test_complex() {
331        assert_eq!(
332            eval(
333                "Some([
334    Room ( width: 20, height: 5, name: \"The Room\" ),
335
336    (
337        width: 10.0,
338        height: 10.0,
339        name: \"Another room\",
340        enemy_levels: {
341            \"Enemy1\": 3,
342            \"Enemy2\": 5,
343            \"Enemy3\": 7,
344        },
345    ),
346])"
347            ),
348            Value::Option(Some(Box::new(Value::Seq(vec![
349                Value::Map(
350                    vec![
351                        (
352                            Value::String("width".to_owned()),
353                            Value::Number(Number::U8(20)),
354                        ),
355                        (
356                            Value::String("height".to_owned()),
357                            Value::Number(Number::U8(5)),
358                        ),
359                        (
360                            Value::String("name".to_owned()),
361                            Value::String("The Room".to_owned()),
362                        ),
363                    ]
364                    .into_iter()
365                    .collect(),
366                ),
367                Value::Map(
368                    vec![
369                        (
370                            Value::String("width".to_owned()),
371                            Value::Number(Number::F32(10.0.into())),
372                        ),
373                        (
374                            Value::String("height".to_owned()),
375                            Value::Number(Number::F32(10.0.into())),
376                        ),
377                        (
378                            Value::String("name".to_owned()),
379                            Value::String("Another room".to_owned()),
380                        ),
381                        (
382                            Value::String("enemy_levels".to_owned()),
383                            Value::Map(
384                                vec![
385                                    (
386                                        Value::String("Enemy1".to_owned()),
387                                        Value::Number(Number::U8(3)),
388                                    ),
389                                    (
390                                        Value::String("Enemy2".to_owned()),
391                                        Value::Number(Number::U8(5)),
392                                    ),
393                                    (
394                                        Value::String("Enemy3".to_owned()),
395                                        Value::Number(Number::U8(7)),
396                                    ),
397                                ]
398                                .into_iter()
399                                .collect(),
400                            ),
401                        ),
402                    ]
403                    .into_iter()
404                    .collect(),
405                ),
406            ]))))
407        );
408    }
409
410    #[test]
411    fn test_struct() {
412        assert_eq!(
413            eval("(a:42)"),
414            Value::Map(
415                [(
416                    Value::String(String::from("a")),
417                    Value::Number(Number::U8(42))
418                )]
419                .into_iter()
420                .collect()
421            ),
422        );
423        assert_eq!(
424            eval("(r#a:42)"),
425            Value::Map(
426                [(
427                    Value::String(String::from("a")),
428                    Value::Number(Number::U8(42))
429                )]
430                .into_iter()
431                .collect()
432            ),
433        );
434        assert_eq!(
435            "(r#:42)".parse::<Value>().unwrap_err(),
436            crate::error::SpannedError {
437                code: crate::Error::ExpectedString,
438                span: crate::error::Span {
439                    start: crate::error::Position { line: 1, col: 3 },
440                    end: crate::error::Position { line: 1, col: 4 },
441                }
442            },
443        );
444
445        // Check for a failure in Deserializer::check_struct_type
446        // - opening brace triggers the struct type check
447        // - unclosed block comment fails the whitespace skip
448        assert_eq!(
449            "( /*".parse::<Value>().unwrap_err(),
450            crate::error::SpannedError {
451                code: crate::Error::UnclosedBlockComment,
452                span: crate::error::Span {
453                    start: crate::error::Position { line: 1, col: 3 },
454                    end: crate::error::Position { line: 1, col: 5 },
455                }
456            },
457        );
458    }
459}