livesplit_core/run/parser/flitter/
s_expressions.rs1use crate::platform::prelude::*;
5use core::{fmt::Display, num::ParseIntError};
6use serde::{
7 de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor},
8 Deserialize,
9};
10
11#[derive(Debug, snafu::Snafu)]
14pub enum Error {
15 TrailingCharacters,
17 Eof,
19 ExpectedOpeningParenthesis,
21 ExpectedClosingParenthesis,
23 ExpectedString,
25 ParseInt {
27 source: ParseIntError,
29 },
30 InvalidUtf8,
32 #[snafu(display("{error}"))]
34 Custom {
35 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}