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