ron/de/
value.rs

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