livesplit_core/run/parser/flitter/
s_expressions.rs

1//! Implements a serde deserializer for S-Expressions.
2//! <http://people.csail.mit.edu/rivest/Sexp.txt>
3
4use crate::platform::prelude::*;
5use core::{fmt::Display, num::ParseIntError};
6use serde::{
7    de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor},
8    Deserialize,
9};
10
11/// The Error types for splits files that couldn't be parsed by the Flitter
12/// Parser.
13#[derive(Debug, snafu::Snafu)]
14pub enum Error {
15    /// Trailing Characters
16    TrailingCharacters,
17    /// Unexpected end of input
18    Eof,
19    /// Expected an opening parenthesis.
20    ExpectedOpeningParenthesis,
21    /// Expected an closing parenthesis.
22    ExpectedClosingParenthesis,
23    /// Expected a string.
24    ExpectedString,
25    /// Failed to parse an integer.
26    ParseInt {
27        /// The underlying error.
28        source: ParseIntError,
29    },
30    /// Encountered invalid UTF-8 sequence.
31    InvalidUtf8,
32    /// Custom error.
33    #[snafu(display("{error}"))]
34    Custom {
35        /// The underlying error.
36        error: String,
37    },
38}
39
40impl From<ParseIntError> for Error {
41    fn from(source: ParseIntError) -> Self {
42        Self::ParseInt { source }
43    }
44}
45
46impl de::Error for Error {
47    fn custom<T>(msg: T) -> Self
48    where
49        T: Display,
50    {
51        Error::Custom {
52            error: msg.to_string(),
53        }
54    }
55}
56
57pub type Result<T> = core::result::Result<T, Error>;
58
59pub struct Deserializer<'source> {
60    source: &'source str,
61}
62
63impl<'source> Deserializer<'source> {
64    pub const fn from_str(source: &'source str) -> Self {
65        Deserializer { source }
66    }
67
68    fn skip_whitespace(&mut self) {
69        self.source = self.source.trim_start();
70    }
71
72    fn starts_with(&mut self, c: char) -> bool {
73        self.source.starts_with(c)
74    }
75
76    fn strip_char(&mut self, c: char) -> bool {
77        match self.source.strip_prefix(c) {
78            Some(rem) => {
79                self.source = rem;
80                true
81            }
82            None => false,
83        }
84    }
85
86    fn parse_ident(&mut self) -> &'source str {
87        if let Some((pos, _)) = self
88            .source
89            .char_indices()
90            .find(|&(_, c)| c.is_whitespace() || c == ')')
91        {
92            let (before, after) = &self.source.split_at(pos);
93            self.source = after;
94            before
95        } else {
96            self.source
97        }
98    }
99
100    fn parse_string(&mut self) -> Result<&'source str> {
101        if let Some(rem) = self.source.strip_prefix('"') {
102            if let Some((in_str, after)) = rem.split_once('"') {
103                self.source = after;
104                Ok(in_str)
105            } else {
106                Err(Error::Eof)
107            }
108        } else {
109            Ok(self.parse_ident())
110        }
111    }
112
113    fn skip_to_matching_closing(&mut self) -> Result<()> {
114        let mut count = 0;
115        let mut in_string = false;
116        if let Some((pos, _)) = self.source.char_indices().find(|&(_, c)| {
117            if c == '(' {
118                if !in_string {
119                    count += 1;
120                }
121            } else if c == ')' {
122                if !in_string {
123                    if count == 0 {
124                        return true;
125                    } else {
126                        count -= 1;
127                    }
128                }
129            } else if c == '"' {
130                in_string = !in_string;
131            }
132            false
133        }) {
134            self.source = &self.source[pos..];
135            Ok(())
136        } else {
137            self.source = "";
138            Err(Error::Eof)
139        }
140    }
141}
142
143pub fn from_str<'de, T>(source: &'de str) -> Result<T>
144where
145    T: 'de + Deserialize<'de>,
146{
147    let mut deserializer = Deserializer::from_str(source);
148    let t = T::deserialize(&mut deserializer)?;
149    deserializer.skip_whitespace();
150    if deserializer.source.is_empty() {
151        Ok(t)
152    } else {
153        Err(Error::TrailingCharacters)
154    }
155}
156
157impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
158    type Error = Error;
159
160    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
161    where
162        V: Visitor<'de>,
163    {
164        unreachable!()
165    }
166    fn deserialize_bool<V>(self, _visitor: V) -> Result<V::Value>
167    where
168        V: Visitor<'de>,
169    {
170        unreachable!()
171    }
172    fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value>
173    where
174        V: Visitor<'de>,
175    {
176        unreachable!()
177    }
178    fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value>
179    where
180        V: Visitor<'de>,
181    {
182        unreachable!()
183    }
184    fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value>
185    where
186        V: Visitor<'de>,
187    {
188        unreachable!()
189    }
190    fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value>
191    where
192        V: Visitor<'de>,
193    {
194        unreachable!()
195    }
196    fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value>
197    where
198        V: Visitor<'de>,
199    {
200        unreachable!()
201    }
202    fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value>
203    where
204        V: Visitor<'de>,
205    {
206        unreachable!()
207    }
208    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
209    where
210        V: Visitor<'de>,
211    {
212        visitor.visit_u32(self.parse_ident().parse()?)
213    }
214    fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value>
215    where
216        V: Visitor<'de>,
217    {
218        unreachable!()
219    }
220    fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
221    where
222        V: Visitor<'de>,
223    {
224        unreachable!()
225    }
226    fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
227    where
228        V: Visitor<'de>,
229    {
230        unreachable!()
231    }
232    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
233    where
234        V: Visitor<'de>,
235    {
236        unreachable!()
237    }
238    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
239    where
240        V: Visitor<'de>,
241    {
242        visitor.visit_borrowed_str(self.parse_string()?)
243    }
244    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
245    where
246        V: Visitor<'de>,
247    {
248        visitor.visit_borrowed_str(self.parse_string()?)
249    }
250    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
251    where
252        V: Visitor<'de>,
253    {
254        unreachable!()
255    }
256    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
257    where
258        V: Visitor<'de>,
259    {
260        unreachable!()
261    }
262    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
263    where
264        V: Visitor<'de>,
265    {
266        visitor.visit_some(self)
267    }
268    fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
269    where
270        V: Visitor<'de>,
271    {
272        unreachable!()
273    }
274    fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
275    where
276        V: Visitor<'de>,
277    {
278        unreachable!()
279    }
280    fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
281    where
282        V: Visitor<'de>,
283    {
284        unreachable!()
285    }
286    fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
287    where
288        V: Visitor<'de>,
289    {
290        self.skip_whitespace();
291        if self.strip_char('(') {
292            let value = visitor.visit_seq(&mut self)?;
293            if self.strip_char(')') {
294                Ok(value)
295            } else {
296                Err(Error::ExpectedClosingParenthesis)
297            }
298        } else {
299            Err(Error::ExpectedOpeningParenthesis)
300        }
301    }
302    fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
303    where
304        V: Visitor<'de>,
305    {
306        unreachable!()
307    }
308    fn deserialize_tuple_struct<V>(
309        self,
310        _name: &'static str,
311        _len: usize,
312        _visitor: V,
313    ) -> Result<V::Value>
314    where
315        V: Visitor<'de>,
316    {
317        unreachable!()
318    }
319    fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
320    where
321        V: Visitor<'de>,
322    {
323        self.skip_whitespace();
324        if self.strip_char('(') {
325            let value = visitor.visit_map(&mut self)?;
326            if self.strip_char(')') {
327                Ok(value)
328            } else {
329                Err(Error::ExpectedClosingParenthesis)
330            }
331        } else {
332            Err(Error::ExpectedOpeningParenthesis)
333        }
334    }
335    fn deserialize_struct<V>(
336        self,
337        _name: &'static str,
338        _fields: &'static [&'static str],
339        visitor: V,
340    ) -> Result<V::Value>
341    where
342        V: Visitor<'de>,
343    {
344        self.deserialize_map(visitor)
345    }
346    fn deserialize_enum<V>(
347        self,
348        _name: &'static str,
349        _variants: &'static [&'static str],
350        _visitor: V,
351    ) -> Result<V::Value>
352    where
353        V: Visitor<'de>,
354    {
355        unreachable!()
356    }
357    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
358    where
359        V: Visitor<'de>,
360    {
361        visitor.visit_borrowed_str(self.parse_ident())
362    }
363    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
364    where
365        V: Visitor<'de>,
366    {
367        self.skip_to_matching_closing()?;
368        visitor.visit_unit()
369    }
370}
371
372impl<'de> SeqAccess<'de> for &mut Deserializer<'de> {
373    type Error = Error;
374
375    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
376    where
377        T: DeserializeSeed<'de>,
378    {
379        self.skip_whitespace();
380        if self.starts_with(')') {
381            Ok(None)
382        } else {
383            seed.deserialize(&mut **self).map(Some)
384        }
385    }
386}
387
388impl<'de> MapAccess<'de> for &mut Deserializer<'de> {
389    type Error = Error;
390
391    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
392    where
393        K: DeserializeSeed<'de>,
394    {
395        self.skip_whitespace();
396        if self.starts_with(')') {
397            Ok(None)
398        } else if self.strip_char('(') {
399            self.skip_whitespace();
400            seed.deserialize(&mut **self).map(Some)
401        } else {
402            Err(Error::ExpectedOpeningParenthesis)
403        }
404    }
405
406    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
407    where
408        V: DeserializeSeed<'de>,
409    {
410        self.skip_whitespace();
411        let result = seed.deserialize(&mut **self)?;
412        self.skip_whitespace();
413        if self.strip_char(')') {
414            Ok(result)
415        } else {
416            Err(Error::ExpectedClosingParenthesis)
417        }
418    }
419}