use super::str::ImmutableStringDeserializer; use crate::any::{Dynamic, Union}; use crate::result::EvalAltResult; use crate::token::Position; use crate::utils::ImmutableString; use serde::de::{DeserializeSeed, Deserializer, Error, MapAccess, SeqAccess, Visitor}; use serde::Deserialize; #[cfg(not(feature = "no_index"))] use crate::engine::Array; #[cfg(not(feature = "no_object"))] use crate::engine::Map; use crate::stdlib::{any::type_name, fmt}; #[cfg(not(feature = "no_std"))] #[cfg(not(target_arch = "wasm32"))] use crate::stdlib::time::Instant; #[cfg(not(feature = "no_std"))] #[cfg(target_arch = "wasm32")] use instant::Instant; pub struct DynamicDeserializer<'a> { value: &'a Dynamic, } impl<'a> DynamicDeserializer<'a> { pub fn from_dynamic(value: &'a Dynamic) -> Self { Self { value } } pub fn type_error(&self) -> Result> { self.type_error_str(type_name::()) } pub fn type_error_str(&self, name: &str) -> Result> { Err(Box::new(EvalAltResult::ErrorMismatchOutputType( name.into(), self.value.type_name().into(), Position::none(), ))) } } pub fn from_dynamic<'de, T: Deserialize<'de>>( value: &'de Dynamic, ) -> Result> { T::deserialize(&mut DynamicDeserializer::from_dynamic(value)) } impl Error for Box { fn custom(err: T) -> Self { Box::new(EvalAltResult::ErrorRuntime( err.to_string(), Position::none(), )) } } impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { type Error = Box; fn deserialize_any>(self, visitor: V) -> Result> { match &self.value.0 { Union::Unit(_) => self.deserialize_unit(visitor), Union::Bool(_) => self.deserialize_bool(visitor), Union::Str(_) => self.deserialize_str(visitor), Union::Char(_) => self.deserialize_char(visitor), #[cfg(not(feature = "only_i32"))] Union::Int(_) => self.deserialize_i64(visitor), #[cfg(feature = "only_i32")] Union::Int(_) => self.deserialize_i32(visitor), #[cfg(not(feature = "no_float"))] Union::Float(_) => self.deserialize_f64(visitor), #[cfg(not(feature = "no_index"))] Union::Array(_) => self.deserialize_seq(visitor), #[cfg(not(feature = "no_object"))] Union::Map(_) => self.deserialize_map(visitor), Union::FnPtr(_) => unimplemented!(), #[cfg(not(feature = "no_std"))] Union::Variant(value) if value.is::() => unimplemented!(), Union::Variant(value) if value.is::() => self.deserialize_i8(visitor), Union::Variant(value) if value.is::() => self.deserialize_i16(visitor), Union::Variant(value) if value.is::() => self.deserialize_i32(visitor), Union::Variant(value) if value.is::() => self.deserialize_i64(visitor), Union::Variant(value) if value.is::() => self.deserialize_u8(visitor), Union::Variant(value) if value.is::() => self.deserialize_u16(visitor), Union::Variant(value) if value.is::() => self.deserialize_u32(visitor), Union::Variant(value) if value.is::() => self.deserialize_u64(visitor), Union::Variant(_) => self.type_error_str("any"), } } fn deserialize_bool>(self, visitor: V) -> Result> { visitor.visit_bool( self.value .as_bool() .or_else(|_| self.type_error::())?, ) } fn deserialize_i8>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_i8(x)) } fn deserialize_i16>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_i16(x)) } fn deserialize_i32>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_i32(x)) } fn deserialize_i64>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_i64(x)) } fn deserialize_u8>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_u8(x)) } fn deserialize_u16>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_u16(x)) } fn deserialize_u32>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_u32(x)) } fn deserialize_u64>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_u64(x)) } fn deserialize_f32>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_float"))] { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_f32(x)) } #[cfg(feature = "no_float")] self.type_error_str("f32") } fn deserialize_f64>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_float"))] { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_f64(x)) } #[cfg(feature = "no_float")] self.type_error_str("f64") } fn deserialize_char>(self, visitor: V) -> Result> { self.value .downcast_ref::() .map_or_else(|| self.type_error::(), |&x| visitor.visit_char(x)) } fn deserialize_str>(self, visitor: V) -> Result> { self.value.downcast_ref::().map_or_else( || self.type_error::(), |x| visitor.visit_borrowed_str(x.as_str()), ) } fn deserialize_string>( self, visitor: V, ) -> Result> { self.deserialize_str(visitor) } fn deserialize_bytes>(self, _: V) -> Result> { self.type_error_str("bytes array") } fn deserialize_byte_buf>(self, _: V) -> Result> { self.type_error_str("bytes array") } fn deserialize_option>(self, _: V) -> Result> { self.type_error_str("bytes array") } fn deserialize_unit>(self, visitor: V) -> Result> { self.value .downcast_ref::<()>() .map_or_else(|| self.type_error::<(), _>(), |_| visitor.visit_unit()) } fn deserialize_unit_struct>( self, _name: &'static str, visitor: V, ) -> Result> { self.deserialize_unit(visitor) } fn deserialize_newtype_struct>( self, _name: &'static str, visitor: V, ) -> Result> { visitor.visit_newtype_struct(self) } fn deserialize_seq>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_index"))] { self.value.downcast_ref::().map_or_else( || self.type_error::(), |arr| visitor.visit_seq(IterateArray::new(arr.iter())), ) } #[cfg(feature = "no_index")] self.type_error_str("array") } fn deserialize_tuple>( self, _len: usize, visitor: V, ) -> Result> { self.deserialize_seq(visitor) } fn deserialize_tuple_struct>( self, _name: &'static str, _len: usize, visitor: V, ) -> Result> { self.deserialize_seq(visitor) } fn deserialize_map>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_object"))] { self.value.downcast_ref::().map_or_else( || self.type_error::(), |map| visitor.visit_map(IterateMap::new(map.keys(), map.values())), ) } #[cfg(feature = "no_object")] self.type_error_str("map") } fn deserialize_struct>( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result> { self.deserialize_map(visitor) } fn deserialize_enum>( self, _name: &'static str, _variants: &'static [&'static str], _: V, ) -> Result> { self.type_error_str("num") } fn deserialize_identifier>( self, visitor: V, ) -> Result> { self.deserialize_str(visitor) } fn deserialize_ignored_any>( self, visitor: V, ) -> Result> { self.deserialize_any(visitor) } } struct IterateArray<'a, ITER: Iterator> { iter: ITER, } impl<'a, ITER: Iterator> IterateArray<'a, ITER> { pub fn new(iter: ITER) -> Self { Self { iter } } } impl<'a: 'de, 'de, ITER: Iterator> SeqAccess<'de> for IterateArray<'a, ITER> { type Error = Box; fn next_element_seed>( &mut self, seed: T, ) -> Result, Box> { match self.iter.next() { None => Ok(None), Some(item) => seed .deserialize(&mut DynamicDeserializer::from_dynamic(item)) .map(Some), } } } struct IterateMap< 'a, KEYS: Iterator, VALUES: Iterator, > { keys: KEYS, values: VALUES, } impl<'a, KEYS: Iterator, VALUES: Iterator> IterateMap<'a, KEYS, VALUES> { pub fn new(keys: KEYS, values: VALUES) -> Self { Self { keys, values } } } impl< 'a: 'de, 'de, KEYS: Iterator, VALUES: Iterator, > MapAccess<'de> for IterateMap<'a, KEYS, VALUES> { type Error = Box; fn next_key_seed>( &mut self, seed: K, ) -> Result, Box> { match self.keys.next() { None => Ok(None), Some(item) => seed .deserialize(&mut ImmutableStringDeserializer::from_str(item)) .map(Some), } } fn next_value_seed>( &mut self, seed: V, ) -> Result> { seed.deserialize(&mut DynamicDeserializer::from_dynamic( self.values.next().unwrap(), )) } }