Merge branch 'master' of https://github.com/schungx/rhai
This commit is contained in:
182
src/serde/de.rs
182
src/serde/de.rs
@@ -7,7 +7,10 @@ use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::utils::ImmutableString;
|
||||
|
||||
use serde::de::{DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||
use serde::de::{
|
||||
DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, MapAccess, SeqAccess,
|
||||
VariantAccess, Visitor,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
@@ -49,6 +52,20 @@ impl<'de> DynamicDeserializer<'de> {
|
||||
Position::none(),
|
||||
)))
|
||||
}
|
||||
fn deserialize_int<V: Visitor<'de>>(
|
||||
&mut self,
|
||||
v: crate::INT,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
{
|
||||
visitor.visit_i64(v)
|
||||
}
|
||||
#[cfg(feature = "only_i32")]
|
||||
{
|
||||
visitor.visit_i32(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize a `Dynamic` value into a Rust type that implements `serde::Deserialize`.
|
||||
@@ -159,51 +176,87 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
}
|
||||
|
||||
fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<i8>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i8(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<i8>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i8(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<i16>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i16(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<i16>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i16(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<i32>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i32(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else if cfg!(feature = "only_i32") {
|
||||
self.type_error()
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<i32>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i32(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<i64>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i64(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else if cfg!(not(feature = "only_i32")) {
|
||||
self.type_error()
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<i64>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_i64(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<u8>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u8(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<u8>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u8(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<u16>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u16(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<u16>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u16(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<u32>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u32(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<u32>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u32(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.value
|
||||
.downcast_ref::<u64>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u64(x))
|
||||
if let Ok(v) = self.value.as_int() {
|
||||
self.deserialize_int(v, visitor)
|
||||
} else {
|
||||
self.value
|
||||
.downcast_ref::<u64>()
|
||||
.map_or_else(|| self.type_error(), |&x| visitor.visit_u64(x))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
@@ -334,9 +387,30 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> {
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
_: V,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Box<EvalAltResult>> {
|
||||
self.type_error()
|
||||
if let Ok(s) = self.value.as_str() {
|
||||
visitor.visit_enum(s.into_deserializer())
|
||||
} else {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
if let Some(map) = self.value.downcast_ref::<Map>() {
|
||||
let mut iter = map.iter();
|
||||
let first = iter.next();
|
||||
let second = iter.next();
|
||||
if let (Some((key, value)), None) = (first, second) {
|
||||
visitor.visit_enum(EnumDeserializer {
|
||||
tag: &key,
|
||||
content: DynamicDeserializer::from_dynamic(value),
|
||||
})
|
||||
} else {
|
||||
self.type_error()
|
||||
}
|
||||
} else {
|
||||
self.type_error()
|
||||
}
|
||||
#[cfg(feature = "no_object")]
|
||||
return self.type_error();
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V: Visitor<'de>>(
|
||||
@@ -444,3 +518,57 @@ where
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
struct EnumDeserializer<'t, 'de: 't> {
|
||||
tag: &'t str,
|
||||
content: DynamicDeserializer<'de>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
impl<'t, 'de> EnumAccess<'de> for EnumDeserializer<'t, 'de> {
|
||||
type Error = Box<EvalAltResult>;
|
||||
type Variant = Self;
|
||||
|
||||
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
|
||||
where
|
||||
V: DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(self.tag.into_deserializer())
|
||||
.map(|v| (v, self))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
impl<'t, 'de> VariantAccess<'de> for EnumDeserializer<'t, 'de> {
|
||||
type Error = Box<EvalAltResult>;
|
||||
|
||||
fn unit_variant(mut self) -> Result<(), Self::Error> {
|
||||
Deserialize::deserialize(&mut self.content)
|
||||
}
|
||||
|
||||
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(&mut self.content)
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.content.deserialize_tuple(len, visitor)
|
||||
}
|
||||
|
||||
fn struct_variant<V>(
|
||||
mut self,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.content.deserialize_struct("", fields, visitor)
|
||||
}
|
||||
}
|
||||
|
145
src/serde/ser.rs
145
src/serde/ser.rs
@@ -103,10 +103,16 @@ impl Serializer for &mut DynamicSerializer {
|
||||
type SerializeSeq = DynamicSerializer;
|
||||
type SerializeTuple = DynamicSerializer;
|
||||
type SerializeTupleStruct = DynamicSerializer;
|
||||
type SerializeTupleVariant = DynamicSerializer;
|
||||
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||
type SerializeTupleVariant = TupleVariantSerializer;
|
||||
#[cfg(any(feature = "no_object", feature = "no_index"))]
|
||||
type SerializeTupleVariant = serde::ser::Impossible<Dynamic, Box<EvalAltResult>>;
|
||||
type SerializeMap = DynamicSerializer;
|
||||
type SerializeStruct = DynamicSerializer;
|
||||
type SerializeStructVariant = DynamicSerializer;
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
type SerializeStructVariant = StructVariantSerializer;
|
||||
#[cfg(feature = "no_object")]
|
||||
type SerializeStructVariant = serde::ser::Impossible<Dynamic, Box<EvalAltResult>>;
|
||||
|
||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
Ok(v.into())
|
||||
@@ -162,7 +168,7 @@ impl Serializer for &mut DynamicSerializer {
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
return self.serialize_i64(i64::from(v));
|
||||
#[cfg(feature = "only_i32")]
|
||||
if v > i32::MAX as u64 {
|
||||
if v > i32::MAX as u32 {
|
||||
return Ok(Dynamic::from(v));
|
||||
} else {
|
||||
return self.serialize_i32(v as i32);
|
||||
@@ -244,10 +250,20 @@ impl Serializer for &mut DynamicSerializer {
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
variant: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
value.serialize(&mut *self)
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
{
|
||||
let content = to_dynamic(value)?;
|
||||
make_variant(variant, content)
|
||||
}
|
||||
#[cfg(feature = "no_object")]
|
||||
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"map".into(),
|
||||
Position::none(),
|
||||
)));
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> {
|
||||
@@ -277,10 +293,26 @@ impl Serializer for &mut DynamicSerializer {
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Box<EvalAltResult>> {
|
||||
self.serialize_seq(Some(len))
|
||||
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||
return Ok(TupleVariantSerializer {
|
||||
variant,
|
||||
array: Array::with_capacity(len),
|
||||
});
|
||||
#[cfg(any(feature = "no_object", feature = "no_index"))]
|
||||
{
|
||||
#[cfg(feature = "no_object")]
|
||||
let err_type = "map";
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
let err_type = "array";
|
||||
Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
err_type.into(),
|
||||
Position::none(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Box<EvalAltResult>> {
|
||||
@@ -306,10 +338,20 @@ impl Serializer for &mut DynamicSerializer {
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Box<EvalAltResult>> {
|
||||
self.serialize_map(Some(len))
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
return Ok(StructVariantSerializer {
|
||||
variant,
|
||||
map: Map::with_capacity(len),
|
||||
});
|
||||
#[cfg(feature = "no_object")]
|
||||
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||
"Dynamic".into(),
|
||||
"map".into(),
|
||||
Position::none(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,33 +437,6 @@ impl SerializeTupleStruct for DynamicSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializeTupleVariant for DynamicSerializer {
|
||||
type Ok = Dynamic;
|
||||
type Error = Box<EvalAltResult>;
|
||||
|
||||
fn serialize_field<T: ?Sized + Serialize>(
|
||||
&mut self,
|
||||
value: &T,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
{
|
||||
let value = value.serialize(&mut *self)?;
|
||||
let arr = self.value.downcast_mut::<Array>().unwrap();
|
||||
arr.push(value);
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(feature = "no_index")]
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
return Ok(self.value);
|
||||
#[cfg(feature = "no_index")]
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializeMap for DynamicSerializer {
|
||||
type Ok = Dynamic;
|
||||
type Error = Box<EvalAltResult>;
|
||||
@@ -520,7 +535,39 @@ impl SerializeStruct for DynamicSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
impl SerializeStructVariant for DynamicSerializer {
|
||||
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||
pub struct TupleVariantSerializer {
|
||||
variant: &'static str,
|
||||
array: Array,
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||
impl SerializeTupleVariant for TupleVariantSerializer {
|
||||
type Ok = Dynamic;
|
||||
type Error = Box<EvalAltResult>;
|
||||
|
||||
fn serialize_field<T: ?Sized + Serialize>(
|
||||
&mut self,
|
||||
value: &T,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
let value = to_dynamic(value)?;
|
||||
self.array.push(value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
make_variant(self.variant, self.array.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub struct StructVariantSerializer {
|
||||
variant: &'static str,
|
||||
map: Map,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
impl SerializeStructVariant for StructVariantSerializer {
|
||||
type Ok = Dynamic;
|
||||
type Error = Box<EvalAltResult>;
|
||||
|
||||
@@ -529,21 +576,19 @@ impl SerializeStructVariant for DynamicSerializer {
|
||||
key: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
{
|
||||
let value = value.serialize(&mut *self)?;
|
||||
let map = self.value.downcast_mut::<Map>().unwrap();
|
||||
map.insert(key.into(), value);
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(feature = "no_object")]
|
||||
unreachable!()
|
||||
let value = to_dynamic(value)?;
|
||||
self.map.insert(key.into(), value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
return Ok(self.value);
|
||||
#[cfg(feature = "no_object")]
|
||||
unreachable!()
|
||||
make_variant(self.variant, self.map.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
fn make_variant(variant: &'static str, value: Dynamic) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let mut map = Map::with_capacity(1);
|
||||
map.insert(variant.into(), value);
|
||||
Ok(map.into())
|
||||
}
|
||||
|
Reference in New Issue
Block a user