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(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.reserve_exact(cap);
229        }
230
231        while let Some(entry) = map.next_entry::<Value, Value>()? {
232            res.insert(entry.0, entry.1);
233        }
234
235        Ok(Value::Map(res))
236    }
237}
238
239#[cfg(test)]
240mod tests {
241    use alloc::vec;
242    use core::str::FromStr;
243
244    use super::*;
245
246    fn eval(s: &str) -> Value {
247        s.parse().expect("Failed to parse")
248    }
249
250    #[test]
251    fn test_none() {
252        assert_eq!(eval("None"), Value::Option(None));
253    }
254
255    #[test]
256    fn test_some() {
257        assert_eq!(eval("Some(())"), Value::Option(Some(Box::new(Value::Unit))));
258        assert_eq!(
259            eval("Some  (  () )"),
260            Value::Option(Some(Box::new(Value::Unit)))
261        );
262    }
263
264    #[test]
265    fn test_tuples_basic() {
266        assert_eq!(
267            eval("(3, 4.0, 5.0)"),
268            Value::Seq(vec![
269                Value::Number(Number::U8(3)),
270                Value::Number(Number::F32(4.0.into())),
271                Value::Number(Number::F32(5.0.into())),
272            ],),
273        );
274    }
275
276    #[test]
277    fn test_tuples_ident() {
278        assert_eq!(
279            eval("(true, 3, 4, 5.0)"),
280            Value::Seq(vec![
281                Value::Bool(true),
282                Value::Number(Number::U8(3)),
283                Value::Number(Number::U8(4)),
284                Value::Number(Number::F32(5.0.into())),
285            ]),
286        );
287    }
288
289    #[test]
290    fn test_tuples_error() {
291        use crate::de::{Error, Position, Span, SpannedError};
292
293        assert_eq!(
294            Value::from_str("Foo:").unwrap_err(),
295            SpannedError {
296                code: Error::TrailingCharacters,
297                span: Span {
298                    start: Position { line: 1, col: 4 },
299                    end: Position { line: 1, col: 4 }
300                }
301            },
302        );
303    }
304
305    #[test]
306    fn test_floats() {
307        assert_eq!(
308            eval("(inf, -inf, NaN)"),
309            Value::Seq(vec![
310                Value::Number(Number::new(core::f32::INFINITY)),
311                Value::Number(Number::new(core::f32::NEG_INFINITY)),
312                Value::Number(Number::new(core::f32::NAN)),
313            ]),
314        );
315    }
316
317    #[test]
318    fn test_complex() {
319        assert_eq!(
320            eval(
321                "Some([
322    Room ( width: 20, height: 5, name: \"The Room\" ),
323
324    (
325        width: 10.0,
326        height: 10.0,
327        name: \"Another room\",
328        enemy_levels: {
329            \"Enemy1\": 3,
330            \"Enemy2\": 5,
331            \"Enemy3\": 7,
332        },
333    ),
334])"
335            ),
336            Value::Option(Some(Box::new(Value::Seq(vec![
337                Value::Map(
338                    vec![
339                        (
340                            Value::String("width".to_owned()),
341                            Value::Number(Number::U8(20)),
342                        ),
343                        (
344                            Value::String("height".to_owned()),
345                            Value::Number(Number::U8(5)),
346                        ),
347                        (
348                            Value::String("name".to_owned()),
349                            Value::String("The Room".to_owned()),
350                        ),
351                    ]
352                    .into_iter()
353                    .collect(),
354                ),
355                Value::Map(
356                    vec![
357                        (
358                            Value::String("width".to_owned()),
359                            Value::Number(Number::F32(10.0.into())),
360                        ),
361                        (
362                            Value::String("height".to_owned()),
363                            Value::Number(Number::F32(10.0.into())),
364                        ),
365                        (
366                            Value::String("name".to_owned()),
367                            Value::String("Another room".to_owned()),
368                        ),
369                        (
370                            Value::String("enemy_levels".to_owned()),
371                            Value::Map(
372                                vec![
373                                    (
374                                        Value::String("Enemy1".to_owned()),
375                                        Value::Number(Number::U8(3)),
376                                    ),
377                                    (
378                                        Value::String("Enemy2".to_owned()),
379                                        Value::Number(Number::U8(5)),
380                                    ),
381                                    (
382                                        Value::String("Enemy3".to_owned()),
383                                        Value::Number(Number::U8(7)),
384                                    ),
385                                ]
386                                .into_iter()
387                                .collect(),
388                            ),
389                        ),
390                    ]
391                    .into_iter()
392                    .collect(),
393                ),
394            ]))))
395        );
396    }
397
398    #[test]
399    fn test_struct() {
400        assert_eq!(
401            eval("(a:42)"),
402            Value::Map(
403                [(
404                    Value::String(String::from("a")),
405                    Value::Number(Number::U8(42))
406                )]
407                .into_iter()
408                .collect()
409            ),
410        );
411        assert_eq!(
412            eval("(r#a:42)"),
413            Value::Map(
414                [(
415                    Value::String(String::from("a")),
416                    Value::Number(Number::U8(42))
417                )]
418                .into_iter()
419                .collect()
420            ),
421        );
422        assert_eq!(
423            "(r#:42)".parse::<Value>().unwrap_err(),
424            crate::error::SpannedError {
425                code: crate::Error::ExpectedString,
426                span: crate::error::Span {
427                    start: crate::error::Position { line: 1, col: 3 },
428                    end: crate::error::Position { line: 1, col: 4 },
429                }
430            },
431        );
432
433        // Check for a failure in Deserializer::check_struct_type
434        // - opening brace triggers the struct type check
435        // - unclosed block comment fails the whitespace skip
436        assert_eq!(
437            "( /*".parse::<Value>().unwrap_err(),
438            crate::error::SpannedError {
439                code: crate::Error::UnclosedBlockComment,
440                span: crate::error::Span {
441                    start: crate::error::Position { line: 1, col: 3 },
442                    end: crate::error::Position { line: 1, col: 5 },
443                }
444            },
445        );
446    }
447}