diff options
author | Haibo Huang <hhb@google.com> | 2021-01-07 18:06:15 -0800 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2021-01-07 18:06:15 -0800 |
commit | 914311bd1f1c0e251d2d7241139c1de29365ec0e (patch) | |
tree | 15427d5f69c1b9fe3ec75ee2be999f2750ca1164 /src/text_format/lexer/str_lit.rs | |
parent | 5ed28a5afee8737e5149e12494d50e5332be3b36 (diff) | |
download | protobuf-914311bd1f1c0e251d2d7241139c1de29365ec0e.tar.gz |
Upgrade rust/crates/protobuf to 2.20.0
Test: make
Change-Id: Ib611629af667df0d09ceb4668cb9512d946503db
Diffstat (limited to 'src/text_format/lexer/str_lit.rs')
-rw-r--r-- | src/text_format/lexer/str_lit.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/text_format/lexer/str_lit.rs b/src/text_format/lexer/str_lit.rs new file mode 100644 index 0000000..caa98f1 --- /dev/null +++ b/src/text_format/lexer/str_lit.rs @@ -0,0 +1,85 @@ +use super::lexer_impl::Lexer; +use super::lexer_impl::LexerError; +use crate::text_format::lexer::ParserLanguage; +use std::fmt; +use std::string::FromUtf8Error; + +#[derive(Debug)] +pub enum StrLitDecodeError { + FromUtf8Error(FromUtf8Error), + // TODO: be more specific + OtherError, +} + +impl fmt::Display for StrLitDecodeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + StrLitDecodeError::FromUtf8Error(e) => write!(f, "{}", e), + StrLitDecodeError::OtherError => write!(f, "String literal decode error"), + } + } +} + +impl std::error::Error for StrLitDecodeError {} + +impl From<LexerError> for StrLitDecodeError { + fn from(_: LexerError) -> Self { + StrLitDecodeError::OtherError + } +} + +impl From<FromUtf8Error> for StrLitDecodeError { + fn from(e: FromUtf8Error) -> Self { + StrLitDecodeError::FromUtf8Error(e) + } +} + +pub type StrLitDecodeResult<T> = Result<T, StrLitDecodeError>; + +/// String literal, both `string` and `bytes`. +#[derive(Clone, Eq, PartialEq, Debug)] +pub struct StrLit { + pub escaped: String, +} + +impl StrLit { + /// May fail if not valid UTF8 + pub fn decode_utf8(&self) -> StrLitDecodeResult<String> { + let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json); + let mut r = Vec::new(); + while !lexer.eof() { + r.push(lexer.next_byte_value()?); + } + Ok(String::from_utf8(r)?) + } + + pub fn decode_bytes(&self) -> StrLitDecodeResult<Vec<u8>> { + let mut lexer = Lexer::new(&self.escaped, ParserLanguage::Json); + let mut r = Vec::new(); + while !lexer.eof() { + r.push(lexer.next_byte_value()?); + } + Ok(r) + } + + pub fn quoted(&self) -> String { + format!("\"{}\"", self.escaped) + } +} + +#[cfg(test)] +mod test { + use crate::text_format::lexer::StrLit; + + #[test] + fn decode_utf8() { + assert_eq!( + "\u{1234}".to_owned(), + StrLit { + escaped: "\\341\\210\\264".to_owned() + } + .decode_utf8() + .unwrap() + ) + } +} |