aboutsummaryrefslogtreecommitdiff
path: root/src/text_format/lexer/str_lit.rs
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2021-01-07 18:06:15 -0800
committerHaibo Huang <hhb@google.com>2021-01-07 18:06:15 -0800
commit914311bd1f1c0e251d2d7241139c1de29365ec0e (patch)
tree15427d5f69c1b9fe3ec75ee2be999f2750ca1164 /src/text_format/lexer/str_lit.rs
parent5ed28a5afee8737e5149e12494d50e5332be3b36 (diff)
downloadprotobuf-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.rs85
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()
+ )
+ }
+}