protobuf_support2/lexer/
str_lit.rs

1use std::fmt;
2use std::string::FromUtf8Error;
3
4use crate::lexer::lexer_impl::Lexer;
5use crate::lexer::parser_language::ParserLanguage;
6
7#[derive(Debug, thiserror::Error)]
8pub enum StrLitDecodeError {
9    #[error(transparent)]
10    FromUtf8Error(#[from] FromUtf8Error),
11    #[error("String literal decode error")]
12    OtherError,
13}
14
15pub type StrLitDecodeResult<T> = Result<T, StrLitDecodeError>;
16
17/// String literal, both `string` and `bytes`.
18#[derive(Clone, Eq, PartialEq, Debug)]
19pub struct StrLit {
20    pub escaped: String,
21}
22
23impl fmt::Display for StrLit {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "\"{}\"", &self.escaped)
26    }
27}
28
29impl StrLit {
30    /// May fail if not valid UTF8
31    pub fn decode_utf8(&self) -> StrLitDecodeResult<String> {
32        let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json);
33        let mut r = Vec::new();
34        while !lexer.eof() {
35            r.push(
36                lexer
37                    .next_byte_value()
38                    .map_err(|_| StrLitDecodeError::OtherError)?,
39            );
40        }
41        Ok(String::from_utf8(r)?)
42    }
43
44    pub fn decode_bytes(&self) -> StrLitDecodeResult<Vec<u8>> {
45        let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json);
46        let mut r = Vec::new();
47        while !lexer.eof() {
48            r.push(
49                lexer
50                    .next_byte_value()
51                    .map_err(|_| StrLitDecodeError::OtherError)?,
52            );
53        }
54        Ok(r)
55    }
56
57    pub fn quoted(&self) -> String {
58        format!("\"{}\"", self.escaped)
59    }
60}
61
62#[cfg(test)]
63mod test {
64    use crate::lexer::str_lit::StrLit;
65
66    #[test]
67    fn decode_utf8() {
68        assert_eq!(
69            "\u{1234}".to_owned(),
70            StrLit {
71                escaped: "\\341\\210\\264".to_owned()
72            }
73            .decode_utf8()
74            .unwrap()
75        )
76    }
77}