diff --git a/src/serde/de.rs b/src/serde/de.rs index 76c31c11..dbf43605 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -8,12 +8,19 @@ use serde::{Deserialize, Deserializer}; use std::prelude::v1::*; use std::{any::type_name, fmt}; -/// Deserializer for [`Dynamic`][crate::Dynamic] which is kept as a reference. -/// -/// The reference is necessary because the deserialized type may hold references -/// (especially `&str`) to the source [`Dynamic`][crate::Dynamic]. -struct DynamicDeserializer<'a> { - value: &'a Dynamic, +/// Deserializer for [`Dynamic`][crate::Dynamic]. +pub struct DynamicDeserializer<'de> { + value: &'de Dynamic, +} + +impl<'de> IntoDeserializer<'de, RhaiError> for &'de Dynamic { + type Deserializer = DynamicDeserializer<'de>; + + #[inline(always)] + #[must_use] + fn into_deserializer(self) -> Self::Deserializer { + DynamicDeserializer { value: self } + } } impl<'de> DynamicDeserializer<'de> { @@ -21,15 +28,20 @@ impl<'de> DynamicDeserializer<'de> { /// /// The reference is necessary because the deserialized type may hold references /// (especially `&str`) to the source [`Dynamic`][crate::Dynamic]. + #[inline(always)] #[must_use] - pub const fn from_dynamic(value: &'de Dynamic) -> Self { + pub const fn new(value: &'de Dynamic) -> Self { Self { value } } /// Shortcut for a type conversion error. + #[cold] + #[inline(always)] fn type_error(&self) -> RhaiResultOf { self.type_error_str(type_name::()) } /// Shortcut for a type conversion error. + #[cold] + #[inline(never)] fn type_error_str(&self, error: &str) -> RhaiResultOf { Err(ERR::ErrorMismatchOutputType( error.into(), @@ -38,11 +50,8 @@ impl<'de> DynamicDeserializer<'de> { ) .into()) } - fn deserialize_int>( - &mut self, - v: crate::INT, - visitor: V, - ) -> RhaiResultOf { + #[inline(always)] + fn deserialize_int>(self, v: crate::INT, visitor: V) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return visitor.visit_i64(v); #[cfg(feature = "only_i32")] @@ -102,10 +111,12 @@ impl<'de> DynamicDeserializer<'de> { /// # } /// ``` pub fn from_dynamic<'de, T: Deserialize<'de>>(value: &'de Dynamic) -> RhaiResultOf { - T::deserialize(&mut DynamicDeserializer::from_dynamic(value)) + T::deserialize(DynamicDeserializer::new(value)) } impl Error for RhaiError { + #[cold] + #[inline(never)] fn custom(err: T) -> Self { LexError::ImproperSymbol(String::new(), err.to_string()) .into_err(Position::NONE) @@ -113,7 +124,7 @@ impl Error for RhaiError { } } -impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { +impl<'de> Deserializer<'de> for DynamicDeserializer<'de> { type Error = RhaiError; fn deserialize_any>(self, visitor: V) -> RhaiResultOf { @@ -458,7 +469,7 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { if let (Some((key, value)), None) = (first, second) { visitor.visit_enum(EnumDeserializer { tag: key, - content: DynamicDeserializer::from_dynamic(value), + content: DynamicDeserializer::new(value), }) } else { self.type_error() @@ -470,10 +481,12 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { } } + #[inline(always)] fn deserialize_identifier>(self, visitor: V) -> RhaiResultOf { self.deserialize_str(visitor) } + #[inline(always)] fn deserialize_ignored_any>(self, visitor: V) -> RhaiResultOf { self.deserialize_any(visitor) } @@ -481,13 +494,14 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { /// `SeqAccess` implementation for arrays. #[cfg(not(feature = "no_index"))] -struct IterateDynamicArray<'a, ITER: Iterator> { +struct IterateDynamicArray<'de, ITER: Iterator> { /// Iterator for a stream of [`Dynamic`][crate::Dynamic] values. iter: ITER, } #[cfg(not(feature = "no_index"))] -impl<'a, ITER: Iterator> IterateDynamicArray<'a, ITER> { +impl<'de, ITER: Iterator> IterateDynamicArray<'de, ITER> { + #[inline(always)] #[must_use] pub const fn new(iter: ITER) -> Self { Self { iter } @@ -495,8 +509,8 @@ impl<'a, ITER: Iterator> IterateDynamicArray<'a, ITER> { } #[cfg(not(feature = "no_index"))] -impl<'a: 'de, 'de, ITER: Iterator> serde::de::SeqAccess<'de> - for IterateDynamicArray<'a, ITER> +impl<'de, ITER: Iterator> serde::de::SeqAccess<'de> + for IterateDynamicArray<'de, ITER> { type Error = RhaiError; @@ -506,17 +520,15 @@ impl<'a: 'de, 'de, ITER: Iterator> serde::de::SeqAccess<'de> ) -> RhaiResultOf> { // Deserialize each item coming out of the iterator. match self.iter.next() { + Some(item) => seed.deserialize(item.into_deserializer()).map(Some), None => Ok(None), - Some(item) => seed - .deserialize(&mut DynamicDeserializer::from_dynamic(item)) - .map(Some), } } } /// `MapAccess` implementation for maps. #[cfg(not(feature = "no_object"))] -struct IterateMap<'a, K: Iterator, V: Iterator> { +struct IterateMap<'de, K: Iterator, V: Iterator> { // Iterator for a stream of [`Dynamic`][crate::Dynamic] keys. keys: K, // Iterator for a stream of [`Dynamic`][crate::Dynamic] values. @@ -524,7 +536,8 @@ struct IterateMap<'a, K: Iterator, V: Iterator, V: Iterator> IterateMap<'a, K, V> { +impl<'de, K: Iterator, V: Iterator> IterateMap<'de, K, V> { + #[inline(always)] #[must_use] pub const fn new(keys: K, values: V) -> Self { Self { keys, values } @@ -532,8 +545,8 @@ impl<'a, K: Iterator, V: Iterator> IterateMa } #[cfg(not(feature = "no_object"))] -impl<'a: 'de, 'de, K: Iterator, V: Iterator> - serde::de::MapAccess<'de> for IterateMap<'a, K, V> +impl<'de, K: Iterator, V: Iterator> serde::de::MapAccess<'de> + for IterateMap<'de, K, V> { type Error = RhaiError; @@ -542,11 +555,9 @@ impl<'a: 'de, 'de, K: Iterator, V: Iterator> seed: S, ) -> RhaiResultOf> { // Deserialize each `Identifier` key coming out of the keys iterator. - match self.keys.next() { + match self.keys.next().map(<_>::into_deserializer) { + Some(d) => seed.deserialize(d).map(Some), None => Ok(None), - Some(item) => seed - .deserialize(&mut super::str::StringSliceDeserializer::from_str(item)) - .map(Some), } } @@ -555,20 +566,18 @@ impl<'a: 'de, 'de, K: Iterator, V: Iterator> seed: S, ) -> RhaiResultOf { // Deserialize each value item coming out of the iterator. - seed.deserialize(&mut DynamicDeserializer::from_dynamic( - self.values.next().unwrap(), - )) + seed.deserialize(self.values.next().unwrap().into_deserializer()) } } #[cfg(not(feature = "no_object"))] -struct EnumDeserializer<'t, 'de: 't> { - tag: &'t str, +struct EnumDeserializer<'de> { + tag: &'de str, content: DynamicDeserializer<'de>, } #[cfg(not(feature = "no_object"))] -impl<'t, 'de> serde::de::EnumAccess<'de> for EnumDeserializer<'t, 'de> { +impl<'de> serde::de::EnumAccess<'de> for EnumDeserializer<'de> { type Error = RhaiError; type Variant = Self; @@ -582,26 +591,30 @@ impl<'t, 'de> serde::de::EnumAccess<'de> for EnumDeserializer<'t, 'de> { } #[cfg(not(feature = "no_object"))] -impl<'t, 'de> serde::de::VariantAccess<'de> for EnumDeserializer<'t, 'de> { +impl<'de> serde::de::VariantAccess<'de> for EnumDeserializer<'de> { type Error = RhaiError; - fn unit_variant(mut self) -> RhaiResultOf<()> { - Deserialize::deserialize(&mut self.content) + #[inline(always)] + fn unit_variant(self) -> RhaiResultOf<()> { + Deserialize::deserialize(self.content) } + #[inline(always)] fn newtype_variant_seed>( - mut self, + self, seed: T, ) -> RhaiResultOf { - seed.deserialize(&mut self.content) + seed.deserialize(self.content) } - fn tuple_variant>(mut self, len: usize, visitor: V) -> RhaiResultOf { + #[inline(always)] + fn tuple_variant>(self, len: usize, visitor: V) -> RhaiResultOf { self.content.deserialize_tuple(len, visitor) } + #[inline(always)] fn struct_variant>( - mut self, + self, fields: &'static [&'static str], visitor: V, ) -> RhaiResultOf { diff --git a/src/serde/deserialize.rs b/src/serde/deserialize.rs index 2f79ef6a..a41f8882 100644 --- a/src/serde/deserialize.rs +++ b/src/serde/deserialize.rs @@ -11,21 +11,28 @@ struct DynamicVisitor; impl<'d> Visitor<'d> for DynamicVisitor { type Value = Dynamic; + #[cold] + #[inline(never)] fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("any type that can be converted into a Dynamic") } + #[inline(always)] fn visit_bool(self, v: bool) -> Result { Ok(v.into()) } + #[inline(always)] fn visit_i8(self, v: i8) -> Result { Ok(INT::from(v).into()) } + #[inline(always)] fn visit_i16(self, v: i16) -> Result { Ok(INT::from(v).into()) } + #[inline(always)] fn visit_i32(self, v: i32) -> Result { Ok(INT::from(v).into()) } + #[inline] fn visit_i64(self, v: i64) -> Result { #[cfg(not(feature = "only_i32"))] { @@ -38,12 +45,15 @@ impl<'d> Visitor<'d> for DynamicVisitor { self.visit_i32(v as i32) } } + #[inline(always)] fn visit_u8(self, v: u8) -> Result { Ok(INT::from(v).into()) } + #[inline(always)] fn visit_u16(self, v: u16) -> Result { Ok(INT::from(v).into()) } + #[inline] fn visit_u32(self, v: u32) -> Result { #[cfg(not(feature = "only_i32"))] { @@ -56,6 +66,7 @@ impl<'d> Visitor<'d> for DynamicVisitor { self.visit_i32(v as i32) } } + #[inline] fn visit_u64(self, v: u64) -> Result { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { @@ -72,6 +83,7 @@ impl<'d> Visitor<'d> for DynamicVisitor { } #[cfg(not(feature = "no_float"))] + #[inline(always)] fn visit_f32(self, v: f32) -> Result { #[cfg(not(feature = "f32_float"))] return self.visit_f64(v as f64); @@ -79,6 +91,7 @@ impl<'d> Visitor<'d> for DynamicVisitor { return Ok(v.into()); } #[cfg(not(feature = "no_float"))] + #[inline(always)] fn visit_f64(self, v: f64) -> Result { #[cfg(not(feature = "f32_float"))] return Ok(v.into()); @@ -88,6 +101,7 @@ impl<'d> Visitor<'d> for DynamicVisitor { #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] + #[inline] fn visit_f32(self, v: f32) -> Result { use rust_decimal::Decimal; use std::convert::TryFrom; @@ -98,6 +112,7 @@ impl<'d> Visitor<'d> for DynamicVisitor { } #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] + #[inline] fn visit_f64(self, v: f64) -> Result { use rust_decimal::Decimal; use std::convert::TryFrom; @@ -107,23 +122,29 @@ impl<'d> Visitor<'d> for DynamicVisitor { .map_err(Error::custom) } + #[inline(always)] fn visit_char(self, v: char) -> Result { self.visit_string(v.to_string()) } + #[inline(always)] fn visit_str(self, v: &str) -> Result { Ok(v.into()) } + #[inline(always)] fn visit_borrowed_str(self, v: &str) -> Result { self.visit_str(v) } + #[inline(always)] fn visit_string(self, v: String) -> Result { Ok(v.into()) } + #[inline(always)] fn visit_unit(self) -> Result { Ok(Dynamic::UNIT) } + #[inline(always)] fn visit_newtype_struct>(self, de: D) -> Result { Deserialize::deserialize(de) } @@ -152,12 +173,14 @@ impl<'d> Visitor<'d> for DynamicVisitor { } impl<'d> Deserialize<'d> for Dynamic { + #[inline(always)] fn deserialize>(de: D) -> Result { de.deserialize_any(DynamicVisitor) } } impl<'d> Deserialize<'d> for ImmutableString { + #[inline] fn deserialize>(de: D) -> Result { let s: String = Deserialize::deserialize(de)?; Ok(s.into()) diff --git a/src/serde/mod.rs b/src/serde/mod.rs index 42b57e6e..4c78a939 100644 --- a/src/serde/mod.rs +++ b/src/serde/mod.rs @@ -6,7 +6,6 @@ mod deserialize; mod metadata; mod ser; mod serialize; -mod str; -pub use de::from_dynamic; -pub use ser::to_dynamic; +pub use de::{from_dynamic, DynamicDeserializer}; +pub use ser::{to_dynamic, DynamicSerializer}; diff --git a/src/serde/ser.rs b/src/serde/ser.rs index 1cdc8e28..4104fd19 100644 --- a/src/serde/ser.rs +++ b/src/serde/ser.rs @@ -1,6 +1,6 @@ //! Implement serialization support of [`Dynamic`][crate::Dynamic] for [`serde`]. -use crate::{Dynamic, Position, RhaiError, RhaiResult, RhaiResultOf, ERR}; +use crate::{Dynamic, Identifier, Position, RhaiError, RhaiResult, RhaiResultOf, ERR}; use serde::ser::{ Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeTuple, SerializeTupleStruct, }; @@ -9,10 +9,10 @@ use std::fmt; #[cfg(feature = "no_std")] use std::prelude::v1::*; -/// Serializer for [`Dynamic`][crate::Dynamic] which is kept as a reference. -struct DynamicSerializer { +/// Serializer for [`Dynamic`][crate::Dynamic]. +pub struct DynamicSerializer { /// Buffer to hold a temporary key. - _key: Dynamic, + _key: Identifier, /// Buffer to hold a temporary value. _value: Dynamic, } @@ -20,10 +20,10 @@ struct DynamicSerializer { impl DynamicSerializer { /// Create a [`DynamicSerializer`] from a [`Dynamic`][crate::Dynamic] value. #[must_use] - pub const fn new(_value: Dynamic) -> Self { + pub const fn new(value: Dynamic) -> Self { Self { - _key: Dynamic::UNIT, - _value, + _key: Identifier::new_const(), + _value: value, } } } @@ -105,10 +105,12 @@ impl Serializer for &mut DynamicSerializer { #[cfg(feature = "no_object")] type SerializeStructVariant = serde::ser::Impossible; + #[inline(always)] fn serialize_bool(self, v: bool) -> RhaiResultOf { Ok(v.into()) } + #[inline(always)] fn serialize_i8(self, v: i8) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -116,6 +118,7 @@ impl Serializer for &mut DynamicSerializer { return self.serialize_i32(i32::from(v)); } + #[inline(always)] fn serialize_i16(self, v: i16) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -123,6 +126,7 @@ impl Serializer for &mut DynamicSerializer { return self.serialize_i32(i32::from(v)); } + #[inline(always)] fn serialize_i32(self, v: i32) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -130,6 +134,7 @@ impl Serializer for &mut DynamicSerializer { return Ok(v.into()); } + #[inline] fn serialize_i64(self, v: i64) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] { @@ -143,6 +148,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline] fn serialize_i128(self, v: i128) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as i128 { @@ -158,6 +164,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline(always)] fn serialize_u8(self, v: u8) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -165,6 +172,7 @@ impl Serializer for &mut DynamicSerializer { return self.serialize_i32(i32::from(v)); } + #[inline(always)] fn serialize_u16(self, v: u16) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); @@ -172,6 +180,7 @@ impl Serializer for &mut DynamicSerializer { return self.serialize_i32(i32::from(v)); } + #[inline] fn serialize_u32(self, v: u32) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] { @@ -185,6 +194,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline] fn serialize_u64(self, v: u64) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { @@ -200,6 +210,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline] fn serialize_u128(self, v: u128) -> RhaiResultOf { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u128 { @@ -215,6 +226,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline] fn serialize_f32(self, v: f32) -> RhaiResultOf { #[cfg(any(not(feature = "no_float"), not(feature = "decimal")))] return Ok(Dynamic::from(v)); @@ -231,6 +243,7 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline] fn serialize_f64(self, v: f64) -> RhaiResultOf { #[cfg(any(not(feature = "no_float"), not(feature = "decimal")))] return Ok(Dynamic::from(v)); @@ -247,14 +260,17 @@ impl Serializer for &mut DynamicSerializer { } } + #[inline(always)] fn serialize_char(self, v: char) -> RhaiResultOf { Ok(v.into()) } + #[inline(always)] fn serialize_str(self, v: &str) -> RhaiResultOf { Ok(v.into()) } + #[inline] fn serialize_bytes(self, _v: &[u8]) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] return Ok(Dynamic::from_blob(_v.to_vec())); @@ -262,28 +278,33 @@ impl Serializer for &mut DynamicSerializer { #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "BLOB's are not supported with 'no_index'".into(), + "BLOB's are not supported under 'no_index'".into(), Position::NONE, ) .into()); } + #[inline(always)] fn serialize_none(self) -> RhaiResultOf { Ok(Dynamic::UNIT) } + #[inline(always)] fn serialize_some(self, value: &T) -> RhaiResultOf { value.serialize(&mut *self) } + #[inline(always)] fn serialize_unit(self) -> RhaiResultOf { Ok(Dynamic::UNIT) } + #[inline(always)] fn serialize_unit_struct(self, _name: &'static str) -> RhaiResultOf { self.serialize_unit() } + #[inline(always)] fn serialize_unit_variant( self, _name: &'static str, @@ -293,6 +314,7 @@ impl Serializer for &mut DynamicSerializer { self.serialize_str(variant) } + #[inline(always)] fn serialize_newtype_struct( self, _name: &'static str, @@ -301,6 +323,7 @@ impl Serializer for &mut DynamicSerializer { value.serialize(&mut *self) } + #[inline] fn serialize_newtype_variant( self, _name: &'static str, @@ -316,28 +339,31 @@ impl Serializer for &mut DynamicSerializer { #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); } + #[inline] fn serialize_seq(self, _len: Option) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] return Ok(DynamicSerializer::new(crate::Array::new().into())); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "arrays are not supported with 'no_index'".into(), + "arrays are not supported under 'no_index'".into(), Position::NONE, ) .into()); } + #[inline(always)] fn serialize_tuple(self, len: usize) -> RhaiResultOf { self.serialize_seq(Some(len)) } + #[inline(always)] fn serialize_tuple_struct( self, _name: &'static str, @@ -346,6 +372,7 @@ impl Serializer for &mut DynamicSerializer { self.serialize_seq(Some(len)) } + #[inline] fn serialize_tuple_variant( self, _name: &'static str, @@ -362,24 +389,26 @@ impl Serializer for &mut DynamicSerializer { #[cfg(any(feature = "no_object", feature = "no_index"))] return Err(ERR::ErrorMismatchDataType( "".into(), - "tuples are not supported with 'no_index' or 'no_object'".into(), + "tuples are not supported under 'no_index' or 'no_object'".into(), Position::NONE, ) .into()); } + #[inline] fn serialize_map(self, _len: Option) -> RhaiResultOf { #[cfg(not(feature = "no_object"))] return Ok(DynamicSerializer::new(crate::Map::new().into())); #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); } + #[inline(always)] fn serialize_struct( self, _name: &'static str, @@ -388,6 +417,7 @@ impl Serializer for &mut DynamicSerializer { self.serialize_map(Some(len)) } + #[inline] fn serialize_struct_variant( self, _name: &'static str, @@ -403,7 +433,7 @@ impl Serializer for &mut DynamicSerializer { #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); @@ -425,20 +455,21 @@ impl SerializeSeq for DynamicSerializer { #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "arrays are not supported with 'no_index'".into(), + "arrays are not supported under 'no_index'".into(), Position::NONE, ) .into()); } // Close the sequence. + #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] return Ok(self._value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "arrays are not supported with 'no_index'".into(), + "arrays are not supported under 'no_index'".into(), Position::NONE, ) .into()); @@ -460,19 +491,20 @@ impl SerializeTuple for DynamicSerializer { #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "tuples are not supported with 'no_index'".into(), + "tuples are not supported under 'no_index'".into(), Position::NONE, ) .into()); } + #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] return Ok(self._value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "tuples are not supported with 'no_index'".into(), + "tuples are not supported under 'no_index'".into(), Position::NONE, ) .into()); @@ -494,19 +526,20 @@ impl SerializeTupleStruct for DynamicSerializer { #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "tuples are not supported with 'no_index'".into(), + "tuples are not supported under 'no_index'".into(), Position::NONE, ) .into()); } + #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_index"))] return Ok(self._value); #[cfg(feature = "no_index")] return Err(ERR::ErrorMismatchDataType( "".into(), - "tuples are not supported with 'no_index'".into(), + "tuples are not supported under 'no_index'".into(), Position::NONE, ) .into()); @@ -520,13 +553,19 @@ impl SerializeMap for DynamicSerializer { fn serialize_key(&mut self, _key: &T) -> RhaiResultOf<()> { #[cfg(not(feature = "no_object"))] { - self._key = _key.serialize(&mut *self)?; + let key = _key.serialize(&mut *self)?; + self._key = key + .into_immutable_string() + .map_err(|typ| { + ERR::ErrorMismatchDataType("string".into(), typ.into(), Position::NONE) + })? + .into(); Ok(()) } #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); @@ -535,20 +574,16 @@ impl SerializeMap for DynamicSerializer { fn serialize_value(&mut self, _value: &T) -> RhaiResultOf<()> { #[cfg(not(feature = "no_object"))] { - let key = std::mem::take(&mut self._key) - .into_immutable_string() - .map_err(|typ| { - ERR::ErrorMismatchDataType("string".into(), typ.into(), Position::NONE) - })?; + let key = std::mem::take(&mut self._key); let value = _value.serialize(&mut *self)?; let map = self._value.downcast_mut::().unwrap(); - map.insert(key.into(), value); + map.insert(key, value); Ok(()) } #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); @@ -573,19 +608,20 @@ impl SerializeMap for DynamicSerializer { #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); } + #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_object"))] return Ok(self._value); #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); @@ -611,19 +647,20 @@ impl SerializeStruct for DynamicSerializer { #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); } + #[inline] fn end(self) -> RhaiResultOf { #[cfg(not(feature = "no_object"))] return Ok(self._value); #[cfg(feature = "no_object")] return Err(ERR::ErrorMismatchDataType( "".into(), - "object maps are not supported with 'no_object'".into(), + "object maps are not supported under 'no_object'".into(), Position::NONE, ) .into()); @@ -632,7 +669,7 @@ impl SerializeStruct for DynamicSerializer { #[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_index"))] -struct TupleVariantSerializer { +pub struct TupleVariantSerializer { variant: &'static str, array: crate::Array, } @@ -649,13 +686,14 @@ impl serde::ser::SerializeTupleVariant for TupleVariantSerializer { Ok(()) } + #[inline] fn end(self) -> RhaiResultOf { make_variant(self.variant, self.array.into()) } } #[cfg(not(feature = "no_object"))] -struct StructVariantSerializer { +pub struct StructVariantSerializer { variant: &'static str, map: crate::Map, } @@ -665,6 +703,7 @@ impl serde::ser::SerializeStructVariant for StructVariantSerializer { type Ok = Dynamic; type Error = RhaiError; + #[inline] fn serialize_field( &mut self, key: &'static str, @@ -675,12 +714,14 @@ impl serde::ser::SerializeStructVariant for StructVariantSerializer { Ok(()) } + #[inline] fn end(self) -> RhaiResultOf { make_variant(self.variant, self.map.into()) } } #[cfg(not(feature = "no_object"))] +#[inline] fn make_variant(variant: &'static str, value: Dynamic) -> RhaiResult { let mut map = crate::Map::new(); map.insert(variant.into(), value); diff --git a/src/serde/serialize.rs b/src/serde/serialize.rs index 579f0d1e..4aaa797e 100644 --- a/src/serde/serialize.rs +++ b/src/serde/serialize.rs @@ -83,6 +83,7 @@ impl Serialize for Dynamic { } impl Serialize for ImmutableString { + #[inline(always)] fn serialize(&self, ser: S) -> Result { ser.serialize_str(self.as_str()) } diff --git a/src/serde/str.rs b/src/serde/str.rs deleted file mode 100644 index df747a42..00000000 --- a/src/serde/str.rs +++ /dev/null @@ -1,143 +0,0 @@ -//! Implement deserialization support of [`ImmutableString`][crate::ImmutableString] for [`serde`]. - -use crate::{Position, RhaiError, RhaiResultOf, ERR}; -use serde::de::{Deserializer, Visitor}; -use std::any::type_name; -#[cfg(feature = "no_std")] -use std::prelude::v1::*; - -/// Deserializer for `ImmutableString`. -pub struct StringSliceDeserializer<'a> { - value: &'a str, -} - -impl<'a> StringSliceDeserializer<'a> { - /// Create an `ImmutableStringDeserializer` from an `&str` reference. - #[must_use] - pub const fn from_str(value: &'a str) -> Self { - Self { value } - } - /// Shortcut for a type conversion error. - fn type_error(&self) -> RhaiResultOf { - Err( - ERR::ErrorMismatchOutputType(type_name::().into(), "string".into(), Position::NONE) - .into(), - ) - } -} - -impl<'de> Deserializer<'de> for &mut StringSliceDeserializer<'de> { - type Error = RhaiError; - - fn deserialize_any>(self, v: V) -> RhaiResultOf { - self.deserialize_str(v) - } - fn deserialize_bool>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_i8>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_i16>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_i32>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_i64>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_u8>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_u16>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_u32>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_u64>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_f32>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_f64>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_char>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_str>(self, v: V) -> RhaiResultOf { - // Only allow deserialization into a string. - v.visit_borrowed_str(self.value) - } - fn deserialize_string>(self, visitor: V) -> RhaiResultOf { - self.deserialize_str(visitor) - } - fn deserialize_bytes>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_byte_buf>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_option>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_unit>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_unit_struct>( - self, - _name: &'static str, - v: V, - ) -> RhaiResultOf { - self.deserialize_unit(v) - } - fn deserialize_newtype_struct>( - self, - _name: &'static str, - v: V, - ) -> RhaiResultOf { - v.visit_newtype_struct(self) - } - fn deserialize_seq>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_tuple>(self, _len: usize, v: V) -> RhaiResultOf { - self.deserialize_seq(v) - } - fn deserialize_tuple_struct>( - self, - _name: &'static str, - _len: usize, - v: V, - ) -> RhaiResultOf { - self.deserialize_seq(v) - } - fn deserialize_map>(self, _: V) -> RhaiResultOf { - self.type_error() - } - fn deserialize_struct>( - self, - _name: &'static str, - _fields: &'static [&'static str], - v: V, - ) -> RhaiResultOf { - self.deserialize_map(v) - } - fn deserialize_enum>( - self, - _name: &'static str, - _variants: &'static [&'static str], - _: V, - ) -> RhaiResultOf { - self.type_error() - } - fn deserialize_identifier>(self, v: V) -> RhaiResultOf { - self.deserialize_str(v) - } - fn deserialize_ignored_any>(self, v: V) -> RhaiResultOf { - self.deserialize_any(v) - } -}