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_i64<E>(self, v: i64) -> Result<Self::Value, E>
53    where
54        E: Error,
55    {
56        Ok(Value::Number(Number::new(v)))
57    }
58
59    #[cfg(feature = "integer128")]
60    fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
61    where
62        E: Error,
63    {
64        self.visit_f64(v as f64)
65    }
66
67    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
68    where
69        E: Error,
70    {
71        Ok(Value::Number(Number::new(v)))
72    }
73
74    #[cfg(feature = "integer128")]
75    fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
76    where
77        E: Error,
78    {
79        self.visit_f64(v as f64)
80    }
81
82    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
83    where
84        E: Error,
85    {
86        Ok(Value::Number(Number::new(v)))
87    }
88
89    fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
90    where
91        E: Error,
92    {
93        Ok(Value::Char(v))
94    }
95
96    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
97    where
98        E: Error,
99    {
100        self.visit_string(v.to_owned())
101    }
102
103    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
104    where
105        E: Error,
106    {
107        Ok(Value::String(v))
108    }
109
110    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
111    where
112        E: Error,
113    {
114        self.visit_byte_buf(v.to_vec())
115    }
116
117    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
118    where
119        E: Error,
120    {
121        self.visit_string(String::from_utf8(v).map_err(|e| Error::custom(format!("{}", e)))?)
122    }
123
124    fn visit_none<E>(self) -> Result<Self::Value, E>
125    where
126        E: Error,
127    {
128        Ok(Value::Option(None))
129    }
130
131    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
132    where
133        D: Deserializer<'de>,
134    {
135        Ok(Value::Option(Some(Box::new(
136            deserializer.deserialize_any(ValueVisitor)?,
137        ))))
138    }
139
140    fn visit_unit<E>(self) -> Result<Self::Value, E>
141    where
142        E: Error,
143    {
144        Ok(Value::Unit)
145    }
146
147    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
148    where
149        D: Deserializer<'de>,
150    {
151        deserializer.deserialize_any(ValueVisitor)
152    }
153
154    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
155    where
156        A: SeqAccess<'de>,
157    {
158        let mut vec = Vec::new();
159        if let Some(cap) = seq.size_hint() {
160            vec.reserve_exact(cap);
161        }
162
163        while let Some(x) = seq.next_element()? {
164            vec.push(x);
165        }
166
167        Ok(Value::Seq(vec))
168    }
169
170    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
171    where
172        A: MapAccess<'de>,
173    {
174        let mut res: Map = Map::new();
175
176        while let Some(entry) = map.next_entry()? {
177            res.insert(entry.0, entry.1);
178        }
179
180        Ok(Value::Map(res))
181    }
182}
183
184#[cfg(test)]
185mod tests {
186    use std::str::FromStr;
187
188    use super::*;
189
190    fn eval(s: &str) -> Value {
191        s.parse().expect("Failed to parse")
192    }
193
194    #[test]
195    fn test_none() {
196        assert_eq!(eval("None"), Value::Option(None));
197    }
198
199    #[test]
200    fn test_some() {
201        assert_eq!(eval("Some(())"), Value::Option(Some(Box::new(Value::Unit))));
202        assert_eq!(
203            eval("Some  (  () )"),
204            Value::Option(Some(Box::new(Value::Unit)))
205        );
206    }
207
208    #[test]
209    fn test_tuples_basic() {
210        assert_eq!(
211            eval("(3, 4.0, 5.0)"),
212            Value::Seq(vec![
213                Value::Number(Number::new(3)),
214                Value::Number(Number::new(4.0)),
215                Value::Number(Number::new(5.0)),
216            ],),
217        );
218    }
219
220    #[test]
221    fn test_tuples_ident() {
222        assert_eq!(
223            eval("(true, 3, 4, 5.0)"),
224            Value::Seq(vec![
225                Value::Bool(true),
226                Value::Number(Number::new(3)),
227                Value::Number(Number::new(4)),
228                Value::Number(Number::new(5.0)),
229            ]),
230        );
231    }
232
233    #[test]
234    fn test_tuples_error() {
235        use crate::de::{Error, Position, SpannedError};
236
237        assert_eq!(
238            Value::from_str("Foo:").unwrap_err(),
239            SpannedError {
240                code: Error::TrailingCharacters,
241                position: Position { col: 4, line: 1 }
242            },
243        );
244    }
245
246    #[test]
247    fn test_floats() {
248        assert_eq!(
249            eval("(inf, -inf, NaN)"),
250            Value::Seq(vec![
251                Value::Number(Number::new(std::f64::INFINITY)),
252                Value::Number(Number::new(std::f64::NEG_INFINITY)),
253                Value::Number(Number::new(std::f64::NAN)),
254            ]),
255        );
256    }
257
258    #[test]
259    fn test_complex() {
260        assert_eq!(
261            eval(
262                "Some([
263    Room ( width: 20, height: 5, name: \"The Room\" ),
264
265    (
266        width: 10.0,
267        height: 10.0,
268        name: \"Another room\",
269        enemy_levels: {
270            \"Enemy1\": 3,
271            \"Enemy2\": 5,
272            \"Enemy3\": 7,
273        },
274    ),
275])"
276            ),
277            Value::Option(Some(Box::new(Value::Seq(vec![
278                Value::Map(
279                    vec![
280                        (
281                            Value::String("width".to_owned()),
282                            Value::Number(Number::new(20)),
283                        ),
284                        (
285                            Value::String("height".to_owned()),
286                            Value::Number(Number::new(5)),
287                        ),
288                        (
289                            Value::String("name".to_owned()),
290                            Value::String("The Room".to_owned()),
291                        ),
292                    ]
293                    .into_iter()
294                    .collect(),
295                ),
296                Value::Map(
297                    vec![
298                        (
299                            Value::String("width".to_owned()),
300                            Value::Number(Number::new(10.0)),
301                        ),
302                        (
303                            Value::String("height".to_owned()),
304                            Value::Number(Number::new(10.0)),
305                        ),
306                        (
307                            Value::String("name".to_owned()),
308                            Value::String("Another room".to_owned()),
309                        ),
310                        (
311                            Value::String("enemy_levels".to_owned()),
312                            Value::Map(
313                                vec![
314                                    (
315                                        Value::String("Enemy1".to_owned()),
316                                        Value::Number(Number::new(3)),
317                                    ),
318                                    (
319                                        Value::String("Enemy2".to_owned()),
320                                        Value::Number(Number::new(5)),
321                                    ),
322                                    (
323                                        Value::String("Enemy3".to_owned()),
324                                        Value::Number(Number::new(7)),
325                                    ),
326                                ]
327                                .into_iter()
328                                .collect(),
329                            ),
330                        ),
331                    ]
332                    .into_iter()
333                    .collect(),
334                ),
335            ]))))
336        );
337    }
338}