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