Skip to main content

vdf_serde/
de.rs

1//! Deserialize VDF data to a Rust data structure
2
3use std::collections::VecDeque;
4
5use serde::Deserialize;
6use serde::de::{self, Visitor, MapAccess, DeserializeSeed, IntoDeserializer};
7use steamy_vdf::parser::{self as vdf_parser, Token};
8
9use crate::error::{Error, Result};
10use std::str::FromStr;
11use std::borrow::{Borrow, Cow};
12
13/// A structure that deserializes VDF into Rust values
14pub struct Deserializer<'de> {
15    input: &'de str,
16    parsed_input: VecDeque<Token<'de>>,
17    top_level: bool,
18}
19
20impl<'de> Deserializer<'de> {
21    /// Creates a VDF deserializer from a `&str`
22    pub fn from_str(input: &'de str) -> Self {
23        Self {
24            input,
25            parsed_input: VecDeque::new(),
26            top_level: true,
27        }
28    }
29}
30
31/// Deserialize an instance of type `T` from a string of VDF text
32///
33/// # Errors
34///
35/// If `s` is not valid VDF, or `T` uses an unsupported Serde data type,
36/// or `T`'s `Deserialize` implementation itself returns an error, an error will be
37/// returned.
38pub fn from_str<'a, T>(s: &'a str) -> Result<T> where T: Deserialize<'a> {
39    let mut deserializer = Deserializer::from_str(s);
40    let t = T::deserialize(&mut deserializer)?;
41    // before we toss a LateEOF, let's make sure we're not erroring on some whitespace
42    let remaining_input = deserializer.input.trim_end();
43    if remaining_input.is_empty() {
44        Ok(t)
45    } else {
46        Err(Error::LateEOF)
47    }
48}
49
50impl<'de> Deserializer<'de> {
51    fn parse_more(&mut self) -> Result<()> {
52        let parsed = vdf_parser::next(self.input.as_bytes());
53        match parsed {
54            nom::IResult::Done(remainder, token) => {
55                // since it came from `as_bytes` this is safe
56                self.input = unsafe { std::str::from_utf8_unchecked(remainder) };
57                self.parsed_input.push_back(token);
58            }
59            nom::IResult::Incomplete(_) => return Err(Error::EarlyEOF),
60            nom::IResult::Error(err) => return Err(Error::Tokenize(err.to_string())),
61        }
62        Ok(())
63    }
64
65    fn parse_more_if_needed(&mut self) -> Result<()> {
66        if self.parsed_input.is_empty() {
67            self.parse_more()?;
68        }
69        Ok(())
70    }
71
72    fn peek_token(&mut self) -> Result<&Token<'de>> {
73        self.parse_more_if_needed()?;
74        self.parsed_input.get(0).ok_or(Error::EarlyEOF)
75    }
76
77    fn next_token(&mut self) -> Result<Token<'de>> {
78        self.parse_more_if_needed()?;
79        self.parsed_input.pop_front().ok_or(Error::EarlyEOF)
80    }
81
82    fn next_token_item(&mut self) -> Result<Cow<'de, str>> {
83        match self.next_token()? {
84            Token::Item(data) => Ok(data),
85            got => Err(Error::Expected("Item", format!("{:?}", got))),
86        }
87    }
88
89    fn parse_next_token_data<T: FromStr>(&mut self) -> Result<T> where T::Err : std::fmt::Display {
90        self.next_token_item()?.parse().map_err(|err: T::Err| Error::StringParse(err.to_string()))
91    }
92}
93
94impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
95    type Error = Error;
96
97    fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
98        Err(Error::UnsupportedType("any"))
99    }
100
101    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
102        match self.next_token()? {
103            Token::Item(data) if data == "0" => visitor.visit_bool(false),
104            Token::Item(data) if data == "1" => visitor.visit_bool(true),
105            got => Err(Error::Expected("bool (\"0\" or \"1\")", format!("{:?}", got))),
106        }
107    }
108
109    fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
110        visitor.visit_i8(self.parse_next_token_data()?)
111    }
112
113    fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
114        visitor.visit_i16(self.parse_next_token_data()?)
115    }
116
117    fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
118        visitor.visit_i32(self.parse_next_token_data()?)
119    }
120
121    fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
122        visitor.visit_i64(self.parse_next_token_data()?)
123    }
124
125    fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
126        visitor.visit_u8(self.parse_next_token_data()?)
127    }
128
129    fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
130        visitor.visit_u16(self.parse_next_token_data()?)
131    }
132
133    fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
134        visitor.visit_u32(self.parse_next_token_data()?)
135    }
136
137    fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
138        visitor.visit_u64(self.parse_next_token_data()?)
139    }
140
141    fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
142        visitor.visit_f32(self.parse_next_token_data()?)
143    }
144
145    fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
146        visitor.visit_f64(self.parse_next_token_data()?)
147    }
148
149    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
150        visitor.visit_char(self.parse_next_token_data()?)
151    }
152
153    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
154        visitor.visit_str(self.next_token_item()?.borrow())
155    }
156
157    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
158        visitor.visit_string(String::from(self.next_token_item()?))
159    }
160
161    fn deserialize_bytes<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
162        Err(Error::UnsupportedType("byte array"))
163    }
164
165    fn deserialize_byte_buf<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
166        Err(Error::UnsupportedType("byte array"))
167    }
168
169    fn deserialize_option<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
170        Err(Error::UnsupportedType("option"))
171    }
172
173    fn deserialize_unit<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
174        Err(Error::UnsupportedType("unit"))
175    }
176
177    fn deserialize_unit_struct<V: Visitor<'de>>(self, _name: &'static str, _visitor: V) -> Result<V::Value> {
178        Err(Error::UnsupportedType("unit_struct"))
179    }
180
181    fn deserialize_newtype_struct<V: Visitor<'de>>(self, name: &'static str, visitor: V) -> Result<V::Value> {
182        if self.top_level {
183            let name_token = self.next_token()?;
184            match name_token {
185                Token::Item(name_token) if name_token == name => {},
186                got => return Err(Error::Expected(name, format!("{:?}", got))),
187            }
188            self.top_level = false;
189        }
190        visitor.visit_newtype_struct(self)
191    }
192
193    fn deserialize_seq<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
194        Err(Error::UnsupportedType("seq"))
195    }
196
197    fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, _visitor: V) -> Result<V::Value> {
198        Err(Error::UnsupportedType("tuple"))
199    }
200
201    fn deserialize_tuple_struct<V: Visitor<'de>>(self, _name: &'static str, _len: usize, _visitor: V) -> Result<V::Value> {
202        Err(Error::UnsupportedType("tuple_struct"))
203    }
204
205    fn deserialize_map<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value> {
206        match self.next_token()? {
207            Token::GroupStart => {
208                let value = visitor.visit_map(TabNewlineSeparated::new(&mut self))?;
209                match self.next_token()? {
210                    Token::GroupEnd => Ok(value),
211                    got => Err(Error::Expected("'}'", format!("{:?}", got))),
212                }
213            }
214            got => Err(Error::Expected("'{'", format!("{:?}", got))),
215        }
216    }
217
218    fn deserialize_struct<V: Visitor<'de>>(
219        self,
220        name: &'static str,
221        _fields: &'static [&'static str],
222        visitor: V
223    ) -> Result<V::Value> {
224        if self.top_level {
225            let name_token = self.next_token()?;
226            match name_token {
227                Token::Item(name_token) if name_token == name => {},
228                got => return Err(Error::Expected(name, format!("{:?}", got))),
229            }
230            self.top_level = false;
231        }
232        self.deserialize_map(visitor)
233    }
234
235    fn deserialize_enum<V: Visitor<'de>>(self, _name: &'static str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value> {
236        visitor.visit_enum(self.next_token_item()?.into_deserializer())
237    }
238
239    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
240        self.deserialize_str(visitor)
241    }
242
243    serde::forward_to_deserialize_any! {
244        ignored_any
245    }
246}
247
248struct TabNewlineSeparated<'a, 'de: 'a> {
249    de: &'a mut Deserializer<'de>,
250}
251
252impl<'a, 'de> TabNewlineSeparated<'a, 'de> {
253    fn new(de: &'a mut Deserializer<'de>) -> Self {
254        Self {
255            de,
256        }
257    }
258}
259
260impl<'de, 'a> MapAccess<'de> for TabNewlineSeparated<'a, 'de> {
261    type Error = Error;
262
263    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
264        where
265            K: DeserializeSeed<'de>,
266    {
267        // Check if there are no more entries.
268        if self.de.peek_token()? == &Token::GroupEnd {
269            return Ok(None);
270        }
271        // Deserialize a map key.
272        seed.deserialize(&mut *self.de).map(Some)
273    }
274
275    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
276        where
277            V: DeserializeSeed<'de>,
278    {
279        // Deserialize a map value.
280        seed.deserialize(&mut *self.de)
281    }
282}
283
284#[cfg(test)]
285mod tests {
286    use super::*;
287
288    #[test]
289    fn test_struct() {
290        #[derive(Deserialize, PartialEq, Debug)]
291        struct Inner {
292            foo: String,
293            bar: bool,
294        }
295
296        #[derive(Deserialize, PartialEq, Debug)]
297        struct Test {
298            int: u32,
299            inner: Inner,
300        }
301
302        let j = concat!(
303            "\"Test\"\n",
304            "{\n",
305            "\t\"int\"\t\"1\"\n",
306            "\t\"inner\"\n",
307            "\t{\n",
308            "\t\t\"foo\"\t\"baz\"\n",
309            "\t\t\"bar\"\t\"0\"\n",
310            "\t}\n",
311            "}"
312        );
313        let expected = Test {
314            int: 1,
315            inner: Inner {
316                foo: "baz".to_string(),
317                bar: false,
318            },
319        };
320        assert_eq!(expected, from_str(j).unwrap());
321    }
322}