From 62f10dde0637b4d5094896fa5897790a1bbf1c9d Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 19 Oct 2024 13:16:05 +0500 Subject: [PATCH] Forward deserialization of primitives in SimpleTypeDeserializer to AtomicDeserializer Content::deserialize_all can be replaced by Content::deserialize_item helper, because when it is used, the self.offset is 0 --- src/de/mod.rs | 26 ---------- src/de/simple_type.rs | 112 +++++++++++++++--------------------------- 2 files changed, 40 insertions(+), 98 deletions(-) diff --git a/src/de/mod.rs b/src/de/mod.rs index a9f6d190..26b4ec4d 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -2309,32 +2309,6 @@ where } } -fn deserialize_bool<'de, V>(value: &[u8], decoder: Decoder, visitor: V) -> Result -where - V: Visitor<'de>, -{ - #[cfg(feature = "encoding")] - { - let value = decoder.decode(value)?; - // No need to unescape because valid boolean representations cannot be escaped - str2bool(value.as_ref(), visitor) - } - - #[cfg(not(feature = "encoding"))] - { - // No need to unescape because valid boolean representations cannot be escaped - match value { - b"true" | b"1" | b"True" | b"TRUE" | b"t" | b"Yes" | b"YES" | b"yes" | b"y" => { - visitor.visit_bool(true) - } - b"false" | b"0" | b"False" | b"FALSE" | b"f" | b"No" | b"NO" | b"no" | b"n" => { - visitor.visit_bool(false) - } - e => Err(DeError::InvalidBoolean(decoder.decode(e)?.into())), - } - } -} - //////////////////////////////////////////////////////////////////////////////////////////////////// /// A structure that deserializes XML into Rust values. diff --git a/src/de/simple_type.rs b/src/de/simple_type.rs index 361955d9..382f7039 100644 --- a/src/de/simple_type.rs +++ b/src/de/simple_type.rs @@ -3,7 +3,7 @@ //! [simple types]: https://www.w3schools.com/xml/el_simpletype.asp //! [as defined]: https://www.w3.org/TR/xmlschema11-1/#Simple_Type_Definition -use crate::de::{deserialize_bool, str2bool, Text}; +use crate::de::{str2bool, Text}; use crate::encoding::Decoder; use crate::errors::serialize::DeError; use crate::escape::unescape; @@ -16,7 +16,8 @@ use std::borrow::Cow; use std::ops::Range; macro_rules! deserialize_num { - ($method:ident, $visit:ident) => { + ($method:ident => $visit:ident) => { + #[inline] fn $method(self, visitor: V) -> Result where V: Visitor<'de>, @@ -24,13 +25,19 @@ macro_rules! deserialize_num { visitor.$visit(self.content.as_str().parse()?) } }; - ($method:ident => $visit:ident) => { +} + +macro_rules! deserialize_primitive { + ($method:ident) => { fn $method(self, visitor: V) -> Result where V: Visitor<'de>, { - let string = self.decode()?; - visitor.$visit(string.as_str().parse()?) + let de = AtomicDeserializer { + content: self.decode()?, + escaped: self.escaped, + }; + de.$method(visitor) } }; } @@ -86,28 +93,7 @@ impl<'de, 'a> Content<'de, 'a> { } /// Supply to the visitor a borrowed string, a string slice, or an owned - /// string depending on the kind of input. Unlike [`Self::deserialize_item`], - /// the whole [`Self::Owned`] string will be passed to the visitor. - /// - /// Calls - /// - `visitor.visit_borrowed_str` if data borrowed from the input - /// - `visitor.visit_str` if data borrowed from another source - /// - `visitor.visit_string` if data owned by this type - #[inline] - fn deserialize_all(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Content::Input(s) => visitor.visit_borrowed_str(s), - Content::Slice(s) => visitor.visit_str(s), - Content::Owned(s, _) => visitor.visit_string(s), - } - } - - /// Supply to the visitor a borrowed string, a string slice, or an owned - /// string depending on the kind of input. Unlike [`Self::deserialize_all`], - /// only part of [`Self::Owned`] string will be passed to the visitor. + /// string depending on the kind of input. /// /// Calls /// - `visitor.visit_borrowed_str` if data borrowed from the input @@ -177,23 +163,23 @@ impl<'de, 'a> Deserializer<'de> for AtomicDeserializer<'de, 'a> { str2bool(self.content.as_str(), visitor) } - deserialize_num!(deserialize_i8, visit_i8); - deserialize_num!(deserialize_i16, visit_i16); - deserialize_num!(deserialize_i32, visit_i32); - deserialize_num!(deserialize_i64, visit_i64); + deserialize_num!(deserialize_i8 => visit_i8); + deserialize_num!(deserialize_i16 => visit_i16); + deserialize_num!(deserialize_i32 => visit_i32); + deserialize_num!(deserialize_i64 => visit_i64); - deserialize_num!(deserialize_u8, visit_u8); - deserialize_num!(deserialize_u16, visit_u16); - deserialize_num!(deserialize_u32, visit_u32); - deserialize_num!(deserialize_u64, visit_u64); + deserialize_num!(deserialize_u8 => visit_u8); + deserialize_num!(deserialize_u16 => visit_u16); + deserialize_num!(deserialize_u32 => visit_u32); + deserialize_num!(deserialize_u64 => visit_u64); serde_if_integer128! { - deserialize_num!(deserialize_i128, visit_i128); - deserialize_num!(deserialize_u128, visit_u128); + deserialize_num!(deserialize_i128 => visit_i128); + deserialize_num!(deserialize_u128 => visit_u128); } - deserialize_num!(deserialize_f32, visit_f32); - deserialize_num!(deserialize_f64, visit_f64); + deserialize_num!(deserialize_f32 => visit_f32); + deserialize_num!(deserialize_f64 => visit_f64); /// Forwards deserialization to the [`Self::deserialize_str`] fn deserialize_char(self, visitor: V) -> Result @@ -586,30 +572,27 @@ impl<'de, 'a> Deserializer<'de> for SimpleTypeDeserializer<'de, 'a> { self.deserialize_str(visitor) } - fn deserialize_bool(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - deserialize_bool(&self.content, self.decoder, visitor) - } + deserialize_primitive!(deserialize_bool); - deserialize_num!(deserialize_i8 => visit_i8); - deserialize_num!(deserialize_i16 => visit_i16); - deserialize_num!(deserialize_i32 => visit_i32); - deserialize_num!(deserialize_i64 => visit_i64); + deserialize_primitive!(deserialize_i8); + deserialize_primitive!(deserialize_i16); + deserialize_primitive!(deserialize_i32); + deserialize_primitive!(deserialize_i64); - deserialize_num!(deserialize_u8 => visit_u8); - deserialize_num!(deserialize_u16 => visit_u16); - deserialize_num!(deserialize_u32 => visit_u32); - deserialize_num!(deserialize_u64 => visit_u64); + deserialize_primitive!(deserialize_u8); + deserialize_primitive!(deserialize_u16); + deserialize_primitive!(deserialize_u32); + deserialize_primitive!(deserialize_u64); serde_if_integer128! { - deserialize_num!(deserialize_i128 => visit_i128); - deserialize_num!(deserialize_u128 => visit_u128); + deserialize_primitive!(deserialize_i128); + deserialize_primitive!(deserialize_u128); } - deserialize_num!(deserialize_f32 => visit_f32); - deserialize_num!(deserialize_f64 => visit_f64); + deserialize_primitive!(deserialize_f32); + deserialize_primitive!(deserialize_f64); + + deserialize_primitive!(deserialize_str); /// Forwards deserialization to the [`Self::deserialize_str`] #[inline] @@ -620,21 +603,6 @@ impl<'de, 'a> Deserializer<'de> for SimpleTypeDeserializer<'de, 'a> { self.deserialize_str(visitor) } - fn deserialize_str(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - let content = self.decode()?; - if self.escaped { - match unescape(content.as_str())? { - Cow::Borrowed(_) => content.deserialize_all(visitor), - Cow::Owned(s) => visitor.visit_string(s), - } - } else { - content.deserialize_all(visitor) - } - } - /// Forwards deserialization to the [`Self::deserialize_str`] #[inline] fn deserialize_string(self, visitor: V) -> Result