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