| use std::num::ParseFloatError; |
| use std::num::ParseIntError; |
| |
| use protobuf::reflect::EnumDescriptor; |
| use protobuf::reflect::EnumValueDescriptor; |
| use protobuf::reflect::FieldDescriptor; |
| use protobuf::reflect::MessageDescriptor; |
| use protobuf::reflect::ReflectValueBox; |
| use protobuf::reflect::RuntimeFieldType; |
| use protobuf::reflect::RuntimeType; |
| use protobuf::well_known_types::any::Any; |
| use protobuf::well_known_types::duration::Duration; |
| use protobuf::well_known_types::field_mask::FieldMask; |
| use protobuf::well_known_types::struct_; |
| use protobuf::well_known_types::struct_::ListValue; |
| use protobuf::well_known_types::struct_::NullValue; |
| use protobuf::well_known_types::struct_::Struct; |
| use protobuf::well_known_types::struct_::Value; |
| use protobuf::well_known_types::timestamp::Timestamp; |
| use protobuf::well_known_types::wrappers::BoolValue; |
| use protobuf::well_known_types::wrappers::BytesValue; |
| use protobuf::well_known_types::wrappers::DoubleValue; |
| use protobuf::well_known_types::wrappers::FloatValue; |
| use protobuf::well_known_types::wrappers::Int32Value; |
| use protobuf::well_known_types::wrappers::Int64Value; |
| use protobuf::well_known_types::wrappers::StringValue; |
| use protobuf::well_known_types::wrappers::UInt32Value; |
| use protobuf::well_known_types::wrappers::UInt64Value; |
| use protobuf::Enum; |
| use protobuf::MessageDyn; |
| use protobuf::MessageFull; |
| use protobuf_support::lexer::json_number_lit::JsonNumberLit; |
| use protobuf_support::lexer::lexer_impl::Lexer; |
| use protobuf_support::lexer::lexer_impl::LexerError; |
| use protobuf_support::lexer::loc::Loc; |
| use protobuf_support::lexer::parser_language::ParserLanguage; |
| use protobuf_support::lexer::token::Token; |
| use protobuf_support::lexer::tokenizer::Tokenizer; |
| use protobuf_support::lexer::tokenizer::TokenizerError; |
| |
| use super::base64; |
| use super::float; |
| use super::rfc_3339; |
| use crate::base64::FromBase64Error; |
| use crate::well_known_wrapper::WellKnownWrapper; |
| |
| #[derive(Debug, thiserror::Error)] |
| enum ParseErrorWithoutLocInner { |
| #[error(transparent)] |
| TokenizerError(#[from] TokenizerError), |
| #[error("Unknown field name: `{}`", .0)] |
| UnknownFieldName(String), |
| #[error("Unknown enum variant name: `{}`", .0)] |
| UnknownEnumVariantName(String), |
| #[error(transparent)] |
| FromBase64Error(#[from] FromBase64Error), |
| #[error(transparent)] |
| IncorrectStrLit(#[from] LexerError), |
| #[error("Incorrect duration")] |
| IncorrectDuration, |
| #[error(transparent)] |
| Rfc3339(#[from] rfc_3339::Rfc3339ParseError), |
| #[error(transparent)] |
| ParseIntError(#[from] ParseIntError), |
| #[error(transparent)] |
| ParseFloatError(#[from] ParseFloatError), |
| #[error("Expecting bool")] |
| ExpectingBool, |
| #[error("Expecting string or integer")] |
| ExpectingStrOrInt, |
| #[error("Expecting number")] |
| ExpectingNumber, |
| #[error("Unexpected token")] |
| UnexpectedToken, |
| #[error("Any parsing is not implemented")] |
| AnyParsingIsNotImplemented, |
| #[error("Message not initialized")] |
| MessageNotInitialized, |
| } |
| |
| /// JSON parse error. |
| #[derive(Debug, thiserror::Error)] |
| #[error(transparent)] |
| struct ParseErrorWithoutLoc(ParseErrorWithoutLocInner); |
| |
| impl From<TokenizerError> for ParseErrorWithoutLoc { |
| fn from(e: TokenizerError) -> Self { |
| ParseErrorWithoutLoc(ParseErrorWithoutLocInner::TokenizerError(e)) |
| } |
| } |
| |
| impl From<FromBase64Error> for ParseErrorWithoutLoc { |
| fn from(e: FromBase64Error) -> Self { |
| ParseErrorWithoutLoc(ParseErrorWithoutLocInner::FromBase64Error(e)) |
| } |
| } |
| |
| impl From<ParseIntError> for ParseErrorWithoutLoc { |
| fn from(e: ParseIntError) -> Self { |
| ParseErrorWithoutLoc(ParseErrorWithoutLocInner::ParseIntError(e)) |
| } |
| } |
| |
| impl From<ParseFloatError> for ParseErrorWithoutLoc { |
| fn from(e: ParseFloatError) -> Self { |
| ParseErrorWithoutLoc(ParseErrorWithoutLocInner::ParseFloatError(e)) |
| } |
| } |
| |
| impl From<rfc_3339::Rfc3339ParseError> for ParseErrorWithoutLoc { |
| fn from(e: rfc_3339::Rfc3339ParseError) -> Self { |
| ParseErrorWithoutLoc(ParseErrorWithoutLocInner::Rfc3339(e)) |
| } |
| } |
| |
| /// JSON parse error |
| #[derive(Debug, thiserror::Error)] |
| #[error("{} at {}", error, loc)] |
| pub struct ParseError { |
| error: ParseErrorWithoutLoc, |
| loc: Loc, |
| } |
| |
| type ParseResultWithoutLoc<A> = Result<A, ParseErrorWithoutLoc>; |
| type ParseResult<A> = Result<A, ParseError>; |
| |
| #[derive(Clone)] |
| struct Parser<'a> { |
| tokenizer: Tokenizer<'a>, |
| parse_options: ParseOptions, |
| } |
| |
| trait FromJsonNumber: PartialEq + Sized { |
| fn from_f64(v: f64) -> Self; |
| fn to_f64(&self) -> f64; |
| fn from_string(v: &str) -> ParseResultWithoutLoc<Self>; |
| } |
| |
| impl FromJsonNumber for u32 { |
| fn from_f64(v: f64) -> Self { |
| v as u32 |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self as f64 |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| Ok(v.parse()?) |
| } |
| } |
| |
| impl FromJsonNumber for u64 { |
| fn from_f64(v: f64) -> Self { |
| v as u64 |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self as f64 |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| Ok(v.parse()?) |
| } |
| } |
| |
| impl FromJsonNumber for i32 { |
| fn from_f64(v: f64) -> Self { |
| v as i32 |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self as f64 |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| Ok(v.parse()?) |
| } |
| } |
| |
| impl FromJsonNumber for i64 { |
| fn from_f64(v: f64) -> Self { |
| v as i64 |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self as f64 |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| Ok(v.parse()?) |
| } |
| } |
| |
| impl FromJsonNumber for f32 { |
| fn from_f64(v: f64) -> Self { |
| v as f32 |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self as f64 |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| if v == float::PROTOBUF_JSON_INF { |
| Ok(f32::INFINITY) |
| } else if v == float::PROTOBUF_JSON_MINUS_INF { |
| Ok(f32::NEG_INFINITY) |
| } else if v == float::PROTOBUF_JSON_NAN { |
| Ok(f32::NAN) |
| } else { |
| Ok(v.parse()?) |
| } |
| } |
| } |
| |
| impl FromJsonNumber for f64 { |
| fn from_f64(v: f64) -> Self { |
| v |
| } |
| |
| fn to_f64(&self) -> f64 { |
| *self |
| } |
| |
| fn from_string(v: &str) -> Result<Self, ParseErrorWithoutLoc> { |
| if v == float::PROTOBUF_JSON_INF { |
| Ok(f64::INFINITY) |
| } else if v == float::PROTOBUF_JSON_MINUS_INF { |
| Ok(f64::NEG_INFINITY) |
| } else if v == float::PROTOBUF_JSON_NAN { |
| Ok(f64::NAN) |
| } else { |
| Ok(v.parse()?) |
| } |
| } |
| } |
| |
| impl<'a> Parser<'a> { |
| fn read_bool(&mut self) -> ParseResultWithoutLoc<bool> { |
| if self.tokenizer.next_ident_if_eq("true")? { |
| Ok(true) |
| } else if self.tokenizer.next_ident_if_eq("false")? { |
| Ok(false) |
| } else { |
| Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::ExpectingBool, |
| )) |
| } |
| } |
| |
| fn parse_bool(&self, s: &str) -> ParseResultWithoutLoc<bool> { |
| if s == "true" { |
| Ok(true) |
| } else if s == "false" { |
| Ok(false) |
| } else { |
| Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::ExpectingBool, |
| )) |
| } |
| } |
| |
| fn read_json_number_opt(&mut self) -> ParseResultWithoutLoc<Option<JsonNumberLit>> { |
| Ok(self.tokenizer.next_token_if_map(|t| match t { |
| Token::JsonNumber(v) => Some(v.clone()), |
| _ => None, |
| })?) |
| } |
| |
| fn read_number<V: FromJsonNumber>(&mut self) -> ParseResultWithoutLoc<V> { |
| if let Some(v) = self.read_json_number_opt()? { |
| V::from_string(&v.0) |
| } else if self.tokenizer.lookahead_is_str_lit()? { |
| let v = self.read_string()?; |
| self.parse_number(&v) |
| } else { |
| Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::ExpectingNumber, |
| )) |
| } |
| } |
| |
| fn parse_number<V: FromJsonNumber>(&self, s: &str) -> ParseResultWithoutLoc<V> { |
| V::from_string(s) |
| } |
| |
| fn merge_wrapper<W>(&mut self, w: &mut W) -> ParseResultWithoutLoc<()> |
| where |
| W: WellKnownWrapper, |
| W::Underlying: FromJsonNumber, |
| { |
| *w.get_mut() = self.read_number()?; |
| Ok(()) |
| } |
| |
| fn merge_bool_value(&mut self, w: &mut BoolValue) -> ParseResultWithoutLoc<()> { |
| w.value = self.read_bool()?; |
| Ok(()) |
| } |
| |
| fn merge_string_value(&mut self, w: &mut StringValue) -> ParseResultWithoutLoc<()> { |
| w.value = self.read_string()?; |
| Ok(()) |
| } |
| |
| fn merge_bytes_value(&mut self, w: &mut BytesValue) -> ParseResultWithoutLoc<()> { |
| w.value = self.read_bytes()?; |
| Ok(()) |
| } |
| |
| fn read_u32(&mut self) -> ParseResultWithoutLoc<u32> { |
| self.read_number() |
| } |
| |
| fn read_u64(&mut self) -> ParseResultWithoutLoc<u64> { |
| self.read_number() |
| } |
| |
| fn read_i32(&mut self) -> ParseResultWithoutLoc<i32> { |
| self.read_number() |
| } |
| |
| fn read_i64(&mut self) -> ParseResultWithoutLoc<i64> { |
| self.read_number() |
| } |
| |
| fn read_f32(&mut self) -> ParseResultWithoutLoc<f32> { |
| self.read_number() |
| } |
| |
| fn read_f64(&mut self) -> ParseResultWithoutLoc<f64> { |
| self.read_number() |
| } |
| |
| fn read_string(&mut self) -> ParseResultWithoutLoc<String> { |
| let str_lit = self.tokenizer.next_str_lit()?; |
| |
| let mut lexer = Lexer::new(&str_lit.escaped, ParserLanguage::Json); |
| let mut r = String::new(); |
| while !lexer.eof() { |
| r.push( |
| lexer |
| .next_json_char_value() |
| .map_err(ParseErrorWithoutLocInner::IncorrectStrLit) |
| .map_err(ParseErrorWithoutLoc)?, |
| ); |
| } |
| Ok(r) |
| } |
| |
| fn read_bytes(&mut self) -> ParseResultWithoutLoc<Vec<u8>> { |
| let s = self.read_string()?; |
| self.parse_bytes(&s) |
| } |
| |
| fn parse_bytes(&self, s: &str) -> ParseResultWithoutLoc<Vec<u8>> { |
| Ok(base64::decode(s)?) |
| } |
| |
| fn read_enum(&mut self, descriptor: &EnumDescriptor) -> ParseResultWithoutLoc<i32> { |
| if descriptor.is::<NullValue>() { |
| return Ok(self.read_wk_null_value()?.value()); |
| } |
| |
| if self.tokenizer.lookahead_is_str_lit()? { |
| let name = self.read_string()?; |
| Ok(self.parse_enum(name, descriptor)?.value()) |
| } else if self.tokenizer.lookahead_is_json_number()? { |
| self.read_i32() |
| } else { |
| Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::ExpectingStrOrInt, |
| )) |
| } |
| } |
| |
| fn parse_enum( |
| &self, |
| name: String, |
| descriptor: &EnumDescriptor, |
| ) -> ParseResultWithoutLoc<EnumValueDescriptor> { |
| match descriptor.value_by_name(&name) { |
| Some(v) => Ok(v), |
| None => Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::UnknownEnumVariantName(name), |
| )), |
| } |
| } |
| |
| fn read_wk_null_value(&mut self) -> ParseResultWithoutLoc<NullValue> { |
| self.tokenizer.next_ident_expect_eq("null")?; |
| Ok(NullValue::NULL_VALUE) |
| } |
| |
| fn read_message( |
| &mut self, |
| descriptor: &MessageDescriptor, |
| ) -> ParseResultWithoutLoc<Box<dyn MessageDyn>> { |
| let mut m = descriptor.new_instance(); |
| self.merge_inner(&mut *m)?; |
| Ok(m) |
| } |
| |
| fn read_value(&mut self, t: &RuntimeType) -> ParseResultWithoutLoc<ReflectValueBox> { |
| match t { |
| RuntimeType::I32 => self.read_i32().map(ReflectValueBox::from), |
| RuntimeType::I64 => self.read_i64().map(ReflectValueBox::from), |
| RuntimeType::U32 => self.read_u32().map(ReflectValueBox::from), |
| RuntimeType::U64 => self.read_u64().map(ReflectValueBox::from), |
| RuntimeType::F32 => self.read_f32().map(ReflectValueBox::from), |
| RuntimeType::F64 => self.read_f64().map(ReflectValueBox::from), |
| RuntimeType::Bool => self.read_bool().map(ReflectValueBox::from), |
| RuntimeType::String => self.read_string().map(ReflectValueBox::from), |
| RuntimeType::VecU8 => self.read_bytes().map(ReflectValueBox::from), |
| RuntimeType::Enum(e) => self |
| .read_enum(&e) |
| .map(|v| ReflectValueBox::Enum(e.clone(), v)), |
| RuntimeType::Message(m) => self.read_message(&m).map(ReflectValueBox::from), |
| } |
| } |
| |
| fn merge_singular_field( |
| &mut self, |
| message: &mut dyn MessageDyn, |
| field: &FieldDescriptor, |
| t: &RuntimeType, |
| ) -> ParseResultWithoutLoc<()> { |
| field.set_singular_field(message, self.read_value(t)?); |
| Ok(()) |
| } |
| |
| fn read_list<C>(&mut self, mut read_item: C) -> ParseResultWithoutLoc<()> |
| where |
| C: for<'b> FnMut(&'b mut Self) -> ParseResultWithoutLoc<()>, |
| { |
| if self.tokenizer.next_ident_if_eq("null")? { |
| return Ok(()); |
| } |
| |
| // TODO: better error reporting on wrong field type |
| self.tokenizer.next_symbol_expect_eq('[', "list")?; |
| let mut first = true; |
| while !self.tokenizer.next_symbol_if_eq(']')? { |
| if !first { |
| self.tokenizer.next_symbol_expect_eq(',', "list")?; |
| } |
| first = false; |
| |
| read_item(self)?; |
| } |
| |
| Ok(()) |
| } |
| |
| fn merge_repeated_field( |
| &mut self, |
| message: &mut dyn MessageDyn, |
| field: &FieldDescriptor, |
| t: &RuntimeType, |
| ) -> ParseResultWithoutLoc<()> { |
| let mut repeated = field.mut_repeated(message); |
| repeated.clear(); |
| |
| self.read_list(|s| { |
| repeated.push(s.read_value(t)?); |
| Ok(()) |
| }) |
| } |
| |
| fn merge_wk_list_value(&mut self, list: &mut ListValue) -> ParseResultWithoutLoc<()> { |
| list.values.clear(); |
| |
| self.read_list(|s| { |
| list.values.push(s.read_wk_value()?); |
| Ok(()) |
| }) |
| } |
| |
| fn read_map<K, Fk, Fi>( |
| &mut self, |
| mut parse_key: Fk, |
| mut read_value_and_insert: Fi, |
| ) -> ParseResultWithoutLoc<()> |
| where |
| Fk: for<'b> FnMut(&Self, String) -> ParseResultWithoutLoc<K>, |
| Fi: for<'b> FnMut(&mut Self, K) -> ParseResultWithoutLoc<()>, |
| { |
| if self.tokenizer.next_ident_if_eq("null")? { |
| return Ok(()); |
| } |
| |
| self.tokenizer.next_symbol_expect_eq('{', "map")?; |
| let mut first = true; |
| while !self.tokenizer.next_symbol_if_eq('}')? { |
| if !first { |
| self.tokenizer.next_symbol_expect_eq(',', "map")?; |
| } |
| first = false; |
| |
| let key_string = self.read_string()?; |
| let k = parse_key(self, key_string)?; |
| |
| self.tokenizer.next_symbol_expect_eq(':', "map")?; |
| read_value_and_insert(self, k)?; |
| } |
| |
| Ok(()) |
| } |
| |
| fn parse_key(&self, key: String, t: &RuntimeType) -> ParseResultWithoutLoc<ReflectValueBox> { |
| match t { |
| RuntimeType::I32 => self.parse_number::<i32>(&key).map(ReflectValueBox::I32), |
| RuntimeType::I64 => self.parse_number::<i64>(&key).map(ReflectValueBox::I64), |
| RuntimeType::U32 => self.parse_number::<u32>(&key).map(ReflectValueBox::U32), |
| RuntimeType::U64 => self.parse_number::<u64>(&key).map(ReflectValueBox::U64), |
| RuntimeType::Bool => self.parse_bool(&key).map(ReflectValueBox::Bool), |
| RuntimeType::String => Ok(ReflectValueBox::String(key)), |
| t @ RuntimeType::F32 |
| | t @ RuntimeType::F64 |
| | t @ RuntimeType::VecU8 |
| | t @ RuntimeType::Enum(..) => panic!("{} cannot be a map key", t), |
| RuntimeType::Message(_) => panic!("message cannot be a map key"), |
| } |
| } |
| |
| fn merge_map_field( |
| &mut self, |
| message: &mut dyn MessageDyn, |
| field: &FieldDescriptor, |
| kt: &RuntimeType, |
| vt: &RuntimeType, |
| ) -> ParseResultWithoutLoc<()> { |
| let mut map = field.mut_map(message); |
| map.clear(); |
| |
| self.read_map( |
| |ss, s| ss.parse_key(s, kt), |
| |s, k| { |
| let v = s.read_value(vt)?; |
| map.insert(k, v); |
| Ok(()) |
| }, |
| ) |
| } |
| |
| fn merge_wk_struct(&mut self, struct_value: &mut Struct) -> ParseResultWithoutLoc<()> { |
| struct_value.fields.clear(); |
| |
| self.read_map( |
| |_, s| Ok(s), |
| |s, k| { |
| let v = s.read_wk_value()?; |
| struct_value.fields.insert(k, v); |
| Ok(()) |
| }, |
| ) |
| } |
| |
| fn skip_json_value(&mut self) -> ParseResultWithoutLoc<()> { |
| if self |
| .tokenizer |
| .next_ident_if_in(&["true", "false", "null"])? |
| .is_some() |
| { |
| } else if self.tokenizer.lookahead_is_str_lit()? { |
| self.tokenizer.next_str_lit()?; |
| } else if self.tokenizer.lookahead_is_json_number()? { |
| self.read_json_number_opt()?; |
| } else if self.tokenizer.lookahead_is_symbol('[')? { |
| self.read_list(|s| s.skip_json_value())?; |
| } else if self.tokenizer.lookahead_is_symbol('{')? { |
| self.read_map(|_, _| Ok(()), |s, ()| s.skip_json_value())?; |
| } else { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::UnexpectedToken, |
| )); |
| } |
| Ok(()) |
| } |
| |
| fn merge_field( |
| &mut self, |
| message: &mut dyn MessageDyn, |
| field: &FieldDescriptor, |
| ) -> ParseResultWithoutLoc<()> { |
| match field.runtime_field_type() { |
| RuntimeFieldType::Singular(t) => self.merge_singular_field(message, field, &t), |
| RuntimeFieldType::Repeated(t) => self.merge_repeated_field(message, field, &t), |
| RuntimeFieldType::Map(kt, vt) => self.merge_map_field(message, field, &kt, &vt), |
| } |
| } |
| |
| fn merge_inner(&mut self, message: &mut dyn MessageDyn) -> ParseResultWithoutLoc<()> { |
| if let Some(duration) = message.downcast_mut() { |
| return self.merge_wk_duration(duration); |
| } |
| |
| if let Some(timestamp) = message.downcast_mut() { |
| return self.merge_wk_timestamp(timestamp); |
| } |
| |
| if let Some(field_mask) = message.downcast_mut() { |
| return self.merge_wk_field_mask(field_mask); |
| } |
| |
| if let Some(value) = message.downcast_mut() { |
| return self.merge_wk_value(value); |
| } |
| |
| if let Some(value) = message.downcast_mut() { |
| return self.merge_wk_any(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<DoubleValue>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<FloatValue>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<Int64Value>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<UInt64Value>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<Int32Value>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<UInt32Value>() { |
| return self.merge_wrapper(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<BoolValue>() { |
| return self.merge_bool_value(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<StringValue>() { |
| return self.merge_string_value(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<BytesValue>() { |
| return self.merge_bytes_value(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<ListValue>() { |
| return self.merge_wk_list_value(value); |
| } |
| |
| if let Some(value) = message.downcast_mut::<Struct>() { |
| return self.merge_wk_struct(value); |
| } |
| |
| let descriptor = message.descriptor_dyn(); |
| |
| self.tokenizer.next_symbol_expect_eq('{', "object")?; |
| let mut first = true; |
| while !self.tokenizer.next_symbol_if_eq('}')? { |
| if !first { |
| self.tokenizer.next_symbol_expect_eq(',', "object")?; |
| } |
| first = false; |
| |
| let field_name = self.read_string()?; |
| // Proto3 JSON parsers are required to accept both |
| // the converted `lowerCamelCase` name and the proto field name. |
| match descriptor.field_by_name_or_json_name(&field_name) { |
| Some(field) => { |
| self.tokenizer.next_symbol_expect_eq(':', "object")?; |
| self.merge_field(message, &field)?; |
| } |
| None if self.parse_options.ignore_unknown_fields => { |
| self.tokenizer.next_symbol_expect_eq(':', "object")?; |
| self.skip_json_value()?; |
| } |
| None => { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::UnknownFieldName(field_name), |
| )) |
| } |
| }; |
| } |
| Ok(()) |
| } |
| |
| fn merge_wk_duration(&mut self, duration: &mut Duration) -> ParseResultWithoutLoc<()> { |
| let s = self.read_string()?; |
| let mut lexer = Lexer::new(&s, ParserLanguage::Json); |
| |
| fn next_dec(lexer: &mut Lexer) -> ParseResultWithoutLoc<(u64, u32)> { |
| let s = lexer.take_while(|c| c >= '0' && c <= '9'); |
| |
| if s.len() == 0 { |
| Ok((0, 0)) |
| } else { |
| match s.parse() { |
| Ok(n) => Ok((n, s.len() as u32)), |
| Err(_) => Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )), |
| } |
| } |
| } |
| |
| let minus = lexer.next_char_if_eq('-'); |
| let seconds = match next_dec(&mut lexer)? { |
| (_, 0) => { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )) |
| } |
| (s, _) => s, |
| }; |
| let nanos = if lexer.next_char_if_eq('.') { |
| let (mut a, mut b) = next_dec(&mut lexer)?; |
| if b > 9 { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )); |
| } |
| while b != 9 { |
| b += 1; |
| a *= 10; |
| } |
| |
| if a > 999_999_999 { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )); |
| } |
| |
| a |
| } else { |
| 0 |
| }; |
| |
| // The suffix "s" is required |
| if !lexer.next_char_if_eq('s') { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )); |
| } |
| |
| if !lexer.eof() { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::IncorrectDuration, |
| )); |
| } |
| |
| if minus { |
| duration.seconds = -(seconds as i64); |
| duration.nanos = -(nanos as i32); |
| } else { |
| duration.seconds = seconds as i64; |
| duration.nanos = nanos as i32; |
| } |
| Ok(()) |
| } |
| |
| fn merge_wk_timestamp(&mut self, timestamp: &mut Timestamp) -> ParseResultWithoutLoc<()> { |
| let s = self.read_string()?; |
| let (seconds, nanos) = rfc_3339::TmUtc::parse_rfc_3339(&s)?; |
| timestamp.seconds = seconds; |
| timestamp.nanos = nanos as i32; |
| Ok(()) |
| } |
| |
| fn merge_wk_field_mask(&mut self, field_mask: &mut FieldMask) -> ParseResultWithoutLoc<()> { |
| let s = self.read_string()?; |
| if !s.is_empty() { |
| field_mask.paths = s.split(',').map(|s| s.to_owned()).collect(); |
| } |
| Ok(()) |
| } |
| |
| fn read_wk_list_value(&mut self) -> ParseResultWithoutLoc<ListValue> { |
| let mut r = ListValue::new(); |
| self.merge_wk_list_value(&mut r)?; |
| Ok(r) |
| } |
| |
| fn read_wk_struct(&mut self) -> ParseResultWithoutLoc<Struct> { |
| let mut r = Struct::new(); |
| self.merge_wk_struct(&mut r)?; |
| Ok(r) |
| } |
| |
| fn merge_wk_value(&mut self, value: &mut Value) -> ParseResultWithoutLoc<()> { |
| if self.tokenizer.lookahead_is_ident("null")? { |
| value.kind = Some(struct_::value::Kind::NullValue( |
| self.read_wk_null_value()?.into(), |
| )); |
| } else if self.tokenizer.lookahead_is_ident("true")? |
| || self.tokenizer.lookahead_is_ident("false")? |
| { |
| value.kind = Some(struct_::value::Kind::BoolValue(self.read_bool()?)); |
| } else if self.tokenizer.lookahead_is_json_number()? { |
| value.kind = Some(struct_::value::Kind::NumberValue(self.read_f64()?)); |
| } else if self.tokenizer.lookahead_is_str_lit()? { |
| value.kind = Some(struct_::value::Kind::StringValue(self.read_string()?)); |
| } else if self.tokenizer.lookahead_is_symbol('[')? { |
| value.kind = Some(struct_::value::Kind::ListValue(self.read_wk_list_value()?)); |
| } else if self.tokenizer.lookahead_is_symbol('{')? { |
| value.kind = Some(struct_::value::Kind::StructValue(self.read_wk_struct()?)); |
| } else { |
| return Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::UnexpectedToken, |
| )); |
| } |
| Ok(()) |
| } |
| |
| fn merge_wk_any(&mut self, _value: &mut Any) -> ParseResultWithoutLoc<()> { |
| Err(ParseErrorWithoutLoc( |
| ParseErrorWithoutLocInner::AnyParsingIsNotImplemented, |
| )) |
| } |
| |
| fn read_wk_value(&mut self) -> ParseResultWithoutLoc<Value> { |
| let mut v = Value::new(); |
| self.merge_wk_value(&mut v)?; |
| Ok(v) |
| } |
| |
| fn merge(&mut self, message: &mut dyn MessageDyn) -> ParseResult<()> { |
| match self.merge_inner(message) { |
| Ok(()) => Ok(()), |
| Err(error) => Err(ParseError { |
| error, |
| loc: self.tokenizer.loc(), |
| }), |
| } |
| } |
| } |
| |
| /// JSON parse options. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// let parse_options = protobuf_json_mapping::ParseOptions { |
| /// ignore_unknown_fields: true, |
| /// ..Default::default() |
| /// }; |
| /// ``` |
| #[derive(Default, Debug, Clone)] |
| pub struct ParseOptions { |
| /// Ignore unknown fields when parsing. |
| /// |
| /// When `true` fields with unknown names are ignored. |
| /// When `false` parser returns an error on unknown field. |
| pub ignore_unknown_fields: bool, |
| /// Prevent initializing `ParseOptions` enumerating all field. |
| pub _future_options: (), |
| } |
| |
| /// Merge JSON into provided message |
| pub fn merge_from_str_with_options( |
| message: &mut dyn MessageDyn, |
| json: &str, |
| parse_options: &ParseOptions, |
| ) -> ParseResult<()> { |
| let mut parser = Parser { |
| tokenizer: Tokenizer::new(json, ParserLanguage::Json), |
| parse_options: parse_options.clone(), |
| }; |
| parser.merge(message) |
| } |
| |
| /// Merge JSON into provided message |
| pub fn merge_from_str(message: &mut dyn MessageDyn, json: &str) -> ParseResult<()> { |
| merge_from_str_with_options(message, json, &ParseOptions::default()) |
| } |
| |
| /// Parse JSON to protobuf message. |
| pub fn parse_dyn_from_str_with_options( |
| d: &MessageDescriptor, |
| json: &str, |
| parse_options: &ParseOptions, |
| ) -> ParseResult<Box<dyn MessageDyn>> { |
| let mut m = d.new_instance(); |
| merge_from_str_with_options(&mut *m, json, parse_options)?; |
| if let Err(_) = m.check_initialized_dyn() { |
| return Err(ParseError { |
| error: ParseErrorWithoutLoc(ParseErrorWithoutLocInner::MessageNotInitialized), |
| loc: Loc::start(), |
| }); |
| } |
| Ok(m) |
| } |
| |
| /// Parse JSON to protobuf message. |
| pub fn parse_dyn_from_str(d: &MessageDescriptor, json: &str) -> ParseResult<Box<dyn MessageDyn>> { |
| parse_dyn_from_str_with_options(d, json, &ParseOptions::default()) |
| } |
| |
| /// Parse JSON to protobuf message. |
| pub fn parse_from_str_with_options<M: MessageFull>( |
| json: &str, |
| parse_options: &ParseOptions, |
| ) -> ParseResult<M> { |
| let m = parse_dyn_from_str_with_options(&M::descriptor(), json, parse_options)?; |
| Ok(*m.downcast_box().unwrap()) |
| } |
| |
| /// Parse JSON to protobuf message. |
| pub fn parse_from_str<M: MessageFull>(json: &str) -> ParseResult<M> { |
| parse_from_str_with_options(json, &ParseOptions::default()) |
| } |