serde_cqcode/de/
core.rs

1use std::{borrow::Cow, collections::VecDeque};
2
3use crate::{data::*, Result, *};
4use model::*;
5use serde::forward_to_deserialize_any;
6
7use super::access::*;
8
9pub struct CQDeserializer<'de> {
10    pub(crate) input: &'de str,
11}
12
13impl<'de> CQDeserializer<'de> {
14    /// Creates a new `Deserializer` with the given input string.
15    ///
16    /// # Arguments
17    ///
18    /// * `input` - A string slice that holds the input to be deserialized.
19    ///
20    /// # Returns
21    ///
22    /// Returns a new instance of `Deserializer`.
23    pub fn new(input: &'de str) -> Self {
24        Self { input }
25    }
26
27    /// Peeks at the next character in the input without consuming it.
28    ///
29    /// # Returns
30    ///
31    /// Returns a `Result` containing the next character if successful, or an `Error::Eof`
32    /// if the input is empty.
33    pub fn peek_char(&self) -> Result<char> {
34        self.input.chars().next().ok_or(Error::Eof)
35    }
36
37    /// Consumes and returns the next character in the input.
38    ///
39    /// # Returns
40    ///
41    /// Returns a `Result` containing the next character if successful, or an `Error::Eof`
42    /// if the input is empty.
43    pub fn next_char(&mut self) -> Result<char> {
44        if let Some((i, ch)) = self.input.char_indices().next() {
45            self.input = &self.input[i + ch.len_utf8()..];
46            Ok(ch)
47        } else {
48            Err(Error::Eof)
49        }
50    }
51
52    pub fn peek_str_until(&self, until: char) -> Result<&str> {
53        if let Some(pos) = self.input.find(until) {
54            Ok(&self.input[..pos])
55        } else {
56            Err(Error::ExpectedDelimiter)
57        }
58    }
59
60    /// Consumes and returns the input string until a specified delimiter is found.
61    ///
62    /// # Arguments
63    ///
64    /// * `until` - The character delimiter to search for.
65    ///
66    /// # Returns
67    ///
68    /// Returns a `Result` containing the substring up to the delimiter if successful, or an
69    /// `Error::ExpectedCodeComma` if the delimiter is not found.
70    pub fn next_str_until(&mut self, until: char) -> Result<&str> {
71        if let Some(pos) = self.input.find(until) {
72            let result = &self.input[..pos];
73            self.input = &self.input[pos..];
74            Ok(result)
75        } else {
76            Err(Error::ExpectedCodeComma)
77        }
78    }
79
80    /// Peeks at a substring of the input with a specified maximum length, without consuming it.
81    ///
82    /// # Arguments
83    ///
84    /// * `max_len` - The maximum length of the substring to peek.
85    ///
86    /// # Returns
87    ///
88    /// Returns a substring of the input with a length up to `max_len`.
89    pub fn peek_str(&self, max_len: usize) -> &str {
90        let len = if max_len > self.input.len() {
91            self.input.len()
92        } else {
93            max_len
94        };
95        &self.input[..len]
96    }
97
98    /// Returns the next substring from the input with a maximum length.
99    ///
100    /// This function extracts a substring from the input with a length up to `max_len`.
101    /// If `max_len` is greater than the remaining input length, it returns the rest of the input.
102    ///
103    /// # Arguments
104    ///
105    /// * `max_len` - The maximum length of the substring to extract.
106    ///
107    /// # Returns
108    ///
109    /// Returns the extracted substring.
110    pub fn next_str(&mut self, max_len: usize) -> &str {
111        let len = if max_len > self.input.len() {
112            self.input.len()
113        } else {
114            max_len
115        };
116        let result = &self.input[..len];
117        self.input = &self.input[len..];
118        result
119    }
120
121    pub fn peek_escaping(&self) -> Result<char> {
122        let code = self.peek_str_until(';')?;
123        let ch = if let Some(ch) = parse_code(code) {
124            ch
125        } else {
126            return Err(Error::UnknownEscaping(code.to_owned()));
127        };
128
129        Ok(ch)
130    }
131
132    pub fn peek_escaped_char(&self) -> Result<char> {
133        match self.peek_char()? {
134            '&' => self.peek_escaping(),
135            ch => Ok(ch),
136        }
137    }
138
139    pub fn next_escaping(&mut self) -> Result<char> {
140        let code = self.next_str_until(';')?;
141        let ch = if let Some(ch) = parse_code(code) {
142            ch
143        } else {
144            return Err(Error::UnknownEscaping(code.to_owned()));
145        };
146
147        self.next_char()?;
148        Ok(ch)
149    }
150
151    pub fn next_escaped_char(&mut self) -> Result<char> {
152        match self.next_char()? {
153            '&' => self.next_escaping(),
154            ch => Ok(ch),
155        }
156    }
157
158    pub fn peek_delimiter(&self) -> Option<char> {
159        for ch in self.input.chars() {
160            if let '[' | ']' | ',' | '=' = ch {
161                return Some(ch);
162            }
163        }
164
165        None
166    }
167
168    pub fn next_raw_str(&mut self) -> &str {
169        let end_pos = self.input.find([']', ',', '=']).unwrap_or(self.input.len());
170        let result = &self.input[..end_pos];
171        self.input = &self.input[end_pos..];
172        result
173    }
174
175    /// Parses the next string from the input until a delimiter is encountered.
176    ///
177    /// This function reads characters from the input and constructs a string
178    /// until it encounters one of the delimiters: ']', ',', or '='. If an '&'
179    /// character is encountered, it attempts to parse an escape sequence.
180    ///
181    /// # Returns
182    ///
183    /// Returns a `Result` containing the parsed string if successful, or an
184    /// `Error` if the end of the input is reached without encountering a
185    /// delimiter.
186    pub fn next_escaped_string(&mut self) -> Result<String> {
187        let mut str = String::new();
188
189        while let Ok(ch) = self.peek_char() {
190            match ch {
191                ']' | ',' | '=' => break,
192                '&' => {
193                    self.next_char()?;
194                    str.push(self.next_escaped_char()?);
195                }
196                _ => {
197                    str.push(self.next_char()?);
198                }
199            }
200        }
201
202        Ok(str)
203    }
204
205    /// Parses a text message from the input until a '[' character is encountered.
206    ///
207    /// This function constructs a `CQCode` with the type "text" and the accumulated
208    /// message data. It handles escape sequences starting with '&' by calling the
209    /// `escaping` method. If the end of the input is reached without encountering
210    /// a '[', it returns an `Error::Eof`.
211    ///
212    /// # Returns
213    ///
214    /// Returns a `Result` containing the `CQCode` if successful, or an `Error::Eof`
215    /// if the end of the input is reached without encountering a '['.
216    pub fn parse_text_msg(&mut self) -> Result<CQCodeModel<'de>> {
217        let mut msg = String::new();
218
219        while let Ok(ch) = self.peek_char() {
220            match ch {
221                '[' => {
222                    break;
223                }
224                '&' => {
225                    self.next_char()?;
226                    msg.push(self.next_escaping()?);
227                }
228                _ => {
229                    msg.push(self.next_char()?);
230                }
231            }
232        }
233
234        Ok(CQCodeModel {
235            cq_type: Cow::Borrowed("text"),
236            data: VecDeque::from([(Cow::Borrowed("text"), ModelValue::String(Cow::Owned(msg)))]),
237        })
238    }
239}
240
241impl<'de> serde::de::Deserializer<'de> for &mut CQDeserializer<'de> {
242    type Error = Error;
243
244    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
245    where
246        V: serde::de::Visitor<'de>,
247    {
248        if self.peek_char()? == '[' {
249            self.next_char()?;
250            let map = CodeRaw::create(&mut *self)?;
251            let result = visitor.visit_map(map)?;
252            if self.peek_char()? != ']' {
253                Err(Error::ExpectedCodeEnd)
254            } else {
255                Ok(result)
256            }
257        } else if let Some('[') | None = self.peek_delimiter() {
258            visitor.visit_map(self.parse_text_msg()?.into_access())
259        } else {
260            self.deserialize_str(visitor)
261        }
262    }
263
264    fn deserialize_map<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
265    where
266        V: serde::de::Visitor<'de>,
267    {
268        if self.peek_char()? == '[' {
269            self.next_char()?;
270            let map = CodeRaw::create(&mut *self)?;
271            let result = visitor.visit_map(map)?;
272            if self.next_char()? != ']' {
273                Err(Error::ExpectedCodeEnd)
274            } else {
275                Ok(result)
276            }
277        } else {
278            visitor.visit_map(self.parse_text_msg()?.into_access())
279        }
280    }
281
282    forward_to_deserialize_any! {
283        struct
284    }
285
286    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
287    where
288        V: serde::de::Visitor<'de>,
289    {
290        match self.next_raw_str() {
291            "1" | "yes" | "true" => visitor.visit_bool(true),
292            "0" | "no" | "false" => visitor.visit_bool(false),
293            v => Err(Error::UnknownValue(v.into(), "bool".into())),
294        }
295    }
296
297    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
298    where
299        V: serde::de::Visitor<'de>,
300    {
301        self.next_escaped_string()
302            .and_then(|r| visitor.visit_string(r))
303    }
304
305    fn deserialize_i64<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
306    where
307        V: serde::de::Visitor<'de>,
308    {
309        let value: i64 = self.next_raw_str().parse()?;
310        visitor.visit_i64(value)
311    }
312
313    fn deserialize_i8<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
314    where
315        V: serde::de::Visitor<'de>,
316    {
317        self.deserialize_i64(visitor)
318    }
319
320    fn deserialize_i16<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
321    where
322        V: serde::de::Visitor<'de>,
323    {
324        self.deserialize_i64(visitor)
325    }
326
327    fn deserialize_i32<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
328    where
329        V: serde::de::Visitor<'de>,
330    {
331        self.deserialize_i64(visitor)
332    }
333
334    fn deserialize_u8<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
335    where
336        V: serde::de::Visitor<'de>,
337    {
338        self.deserialize_i64(visitor)
339    }
340
341    fn deserialize_u16<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
342    where
343        V: serde::de::Visitor<'de>,
344    {
345        self.deserialize_i64(visitor)
346    }
347
348    fn deserialize_u32<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
349    where
350        V: serde::de::Visitor<'de>,
351    {
352        self.deserialize_i64(visitor)
353    }
354
355    fn deserialize_u64<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
356    where
357        V: serde::de::Visitor<'de>,
358    {
359        self.deserialize_i64(visitor)
360    }
361
362    fn deserialize_f32<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
363    where
364        V: serde::de::Visitor<'de>,
365    {
366        self.deserialize_f64(visitor)
367    }
368
369    fn deserialize_f64<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
370    where
371        V: serde::de::Visitor<'de>,
372    {
373        let value = self.next_raw_str();
374        visitor.visit_f64(value.parse()?)
375    }
376
377    fn deserialize_char<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
378    where
379        V: serde::de::Visitor<'de>,
380    {
381        let value = self.next_escaped_string()?;
382        let mut chars = value.chars();
383        if let (Some(ch), None) = (chars.next(), chars.next()) {
384            visitor.visit_char(ch)
385        } else {
386            Err(Error::MismatchedValueType(value, "char".into()))
387        }
388    }
389
390    fn deserialize_string<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
391    where
392        V: serde::de::Visitor<'de>,
393    {
394        let value = self.next_escaped_string()?;
395        visitor.visit_string(value)
396    }
397
398    fn deserialize_bytes<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
399    where
400        V: serde::de::Visitor<'de>,
401    {
402        let value = self.next_raw_str();
403        visitor.visit_bytes(value.as_bytes())
404    }
405
406    fn deserialize_byte_buf<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
407    where
408        V: serde::de::Visitor<'de>,
409    {
410        let value = self.next_raw_str();
411        visitor.visit_byte_buf(value.as_bytes().to_vec())
412    }
413
414    fn deserialize_option<V>(self, _visitor: V) -> std::result::Result<V::Value, Self::Error>
415    where
416        V: serde::de::Visitor<'de>,
417    {
418        Err(Error::UnsupportedType("option".into()))
419    }
420
421    fn deserialize_unit<V>(self, _visitor: V) -> std::result::Result<V::Value, Self::Error>
422    where
423        V: serde::de::Visitor<'de>,
424    {
425        Err(Error::UnsupportedType("unit".into()))
426    }
427
428    fn deserialize_unit_struct<V>(
429        self,
430        _name: &'static str,
431        visitor: V,
432    ) -> std::result::Result<V::Value, Self::Error>
433    where
434        V: serde::de::Visitor<'de>,
435    {
436        self.deserialize_unit(visitor)
437    }
438
439    fn deserialize_newtype_struct<V>(
440        self,
441        _name: &'static str,
442        visitor: V,
443    ) -> std::result::Result<V::Value, Self::Error>
444    where
445        V: serde::de::Visitor<'de>,
446    {
447        visitor.visit_newtype_struct(self)
448    }
449
450    fn deserialize_seq<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
451    where
452        V: serde::de::Visitor<'de>,
453    {
454        visitor.visit_seq(CodeSeq::new(self))
455    }
456
457    fn deserialize_tuple<V>(
458        self,
459        _len: usize,
460        visitor: V,
461    ) -> std::result::Result<V::Value, Self::Error>
462    where
463        V: serde::de::Visitor<'de>,
464    {
465        self.deserialize_seq(visitor)
466    }
467
468    fn deserialize_tuple_struct<V>(
469        self,
470        _name: &'static str,
471        _len: usize,
472        visitor: V,
473    ) -> std::result::Result<V::Value, Self::Error>
474    where
475        V: serde::de::Visitor<'de>,
476    {
477        self.deserialize_seq(visitor)
478    }
479
480    fn deserialize_enum<V>(
481        self,
482        _name: &'static str,
483        _variants: &'static [&'static str],
484        visitor: V,
485    ) -> std::result::Result<V::Value, Self::Error>
486    where
487        V: serde::de::Visitor<'de>,
488    {
489        if self.peek_char()? == '[' {
490            self.next_char()?;
491            let result = visitor.visit_enum(CodeRaw::create(&mut *self)?)?;
492            if self.next_char()? != ']' {
493                Err(Error::ExpectedCodeEnd)
494            } else {
495                Ok(result)
496            }
497        } else if let Some('[') | None = self.peek_delimiter() {
498            visitor.visit_enum(self.parse_text_msg()?.into_access())
499        } else {
500            Err(Error::ExpectedCodeStart)
501        }
502    }
503
504    fn deserialize_identifier<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
505    where
506        V: serde::de::Visitor<'de>,
507    {
508        self.deserialize_str(visitor)
509    }
510
511    fn deserialize_ignored_any<V>(self, visitor: V) -> std::result::Result<V::Value, Self::Error>
512    where
513        V: serde::de::Visitor<'de>,
514    {
515        visitor.visit_unit()
516    }
517}