use crate::any::Dynamic; use crate::result::EvalAltResult; use crate::token::Position; #[cfg(not(feature = "no_index"))] use crate::engine::Array; #[cfg(not(feature = "no_object"))] use crate::engine::Map; use serde::ser::{ Error, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, Serializer, }; use serde::Serialize; use crate::stdlib::{any::type_name, fmt, mem}; pub struct DynamicSerializer { key: Dynamic, value: Dynamic, } impl DynamicSerializer { pub fn new(value: Dynamic) -> Self { Self { key: Default::default(), 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 to_dynamic(value: T) -> Result> { let mut s = DynamicSerializer::new(Default::default()); value.serialize(&mut s) } impl Error for Box { fn custom(err: T) -> Self { Box::new(EvalAltResult::ErrorRuntime( err.to_string(), Position::none(), )) } } impl Serializer for &mut DynamicSerializer { type Ok = Dynamic; type Error = Box; type SerializeSeq = DynamicSerializer; type SerializeTuple = DynamicSerializer; type SerializeTupleStruct = DynamicSerializer; type SerializeTupleVariant = DynamicSerializer; type SerializeMap = DynamicSerializer; type SerializeStruct = DynamicSerializer; type SerializeStructVariant = DynamicSerializer; fn serialize_bool(self, v: bool) -> Result> { Ok(v.into()) } fn serialize_i8(self, v: i8) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] return self.serialize_i32(i32::from(v)); } fn serialize_i16(self, v: i16) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] return self.serialize_i32(i32::from(v)); } fn serialize_i32(self, v: i32) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] return Ok(v.into()); } fn serialize_i64(self, v: i64) -> Result> { #[cfg(not(feature = "only_i32"))] return Ok(v.into()); #[cfg(feature = "only_i32")] if v > i32::MAX as i64 { return Ok(Dynamic::from(v)); } else { return self.serialize_i32(v as i32); } } fn serialize_u8(self, v: u8) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] return self.serialize_i32(i32::from(v)); } fn serialize_u16(self, v: u16) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] return self.serialize_i32(i32::from(v)); } fn serialize_u32(self, v: u32) -> Result> { #[cfg(not(feature = "only_i32"))] return self.serialize_i64(i64::from(v)); #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { return Ok(Dynamic::from(v)); } else { return self.serialize_i32(v as i32); } } fn serialize_u64(self, v: u64) -> Result> { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { return Ok(Dynamic::from(v)); } else { return self.serialize_i64(v as i64); } #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { return Ok(Dynamic::from(v)); } else { return self.serialize_i32(v as i32); } } fn serialize_f32(self, v: f32) -> Result> { #[cfg(not(feature = "no_float"))] return Ok(Dynamic::from(v)); #[cfg(feature = "no_float")] return self.type_error_str("f32"); } fn serialize_f64(self, v: f64) -> Result> { #[cfg(not(feature = "no_float"))] return Ok(v.into()); #[cfg(feature = "no_float")] return self.type_error_str("f64"); } fn serialize_char(self, v: char) -> Result> { Ok(v.into()) } fn serialize_str(self, v: &str) -> Result> { Ok(v.to_string().into()) } fn serialize_bytes(self, _: &[u8]) -> Result> { self.type_error_str("bytes array") } fn serialize_none(self) -> Result> { Ok(().into()) } fn serialize_some( self, value: &T, ) -> Result> { value.serialize(&mut *self) } fn serialize_unit(self) -> Result> { Ok(().into()) } fn serialize_unit_struct(self, _name: &'static str) -> Result> { self.serialize_unit() } fn serialize_unit_variant( self, _name: &'static str, _variant_index: u32, variant: &'static str, ) -> Result> { self.serialize_str(variant) } fn serialize_newtype_struct( self, _name: &'static str, value: &T, ) -> Result> { value.serialize(&mut *self) } fn serialize_newtype_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, value: &T, ) -> Result> { value.serialize(&mut *self) } fn serialize_seq(self, _len: Option) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(DynamicSerializer::new(Array::new().into())); #[cfg(feature = "no_index")] return self.type_error_str("array"); } fn serialize_tuple(self, len: usize) -> Result> { self.serialize_seq(Some(len)) } fn serialize_tuple_struct( self, _name: &'static str, len: usize, ) -> Result> { self.serialize_seq(Some(len)) } fn serialize_tuple_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, len: usize, ) -> Result> { self.serialize_seq(Some(len)) } fn serialize_map(self, _len: Option) -> Result> { #[cfg(not(feature = "no_object"))] return Ok(DynamicSerializer::new(Map::new().into())); #[cfg(feature = "no_object")] return self.type_error_str("map"); } fn serialize_struct( self, _name: &'static str, len: usize, ) -> Result> { self.serialize_map(Some(len)) } fn serialize_struct_variant( self, _name: &'static str, _variant_index: u32, _variant: &'static str, len: usize, ) -> Result> { self.serialize_map(Some(len)) } } impl SerializeSeq for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_element( &mut self, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_index"))] { let value = value.serialize(&mut *self)?; if let Some(arr) = self.value.downcast_mut::() { arr.push(value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_index")] self.type_error_str("array") } // Close the sequence. fn end(self) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(self.value); #[cfg(feature = "no_index")] return self.type_error_str("array"); } } impl SerializeTuple for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_element( &mut self, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_index"))] { let value = value.serialize(&mut *self)?; if let Some(arr) = self.value.downcast_mut::() { arr.push(value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_index")] self.type_error_str("array") } fn end(self) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(self.value); #[cfg(feature = "no_index")] return self.type_error_str("array"); } } impl SerializeTupleStruct for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_field( &mut self, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_index"))] { let value = value.serialize(&mut *self)?; if let Some(arr) = self.value.downcast_mut::() { arr.push(value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_index")] self.type_error_str("array") } fn end(self) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(self.value); #[cfg(feature = "no_index")] return self.type_error_str("array"); } } impl SerializeTupleVariant for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_field( &mut self, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_index"))] { let value = value.serialize(&mut *self)?; if let Some(arr) = self.value.downcast_mut::() { arr.push(value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_index")] self.type_error_str("array") } fn end(self) -> Result> { #[cfg(not(feature = "no_index"))] return Ok(self.value); #[cfg(feature = "no_index")] return self.type_error_str("array"); } } impl SerializeMap for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_key(&mut self, key: &T) -> Result<(), Box> { #[cfg(not(feature = "no_object"))] { self.key = key.serialize(&mut *self)?; Ok(()) } #[cfg(feature = "no_object")] self.type_error_str("map") } fn serialize_value( &mut self, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_object"))] { let key = mem::take(&mut self.key) .take_immutable_string() .or_else(|_| self.type_error::())?; let value = value.serialize(&mut *self)?; if let Some(map) = self.value.downcast_mut::() { map.insert(key, value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_object")] self.type_error_str("map") } fn serialize_entry( &mut self, key: &K, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_object"))] { let key: Dynamic = key.serialize(&mut *self)?; let key = key .take_immutable_string() .or_else(|_| self.type_error::())?; let value = value.serialize(&mut *self)?; if let Some(map) = self.value.downcast_mut::() { map.insert(key, value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_object")] self.type_error_str("map") } fn end(self) -> Result> { #[cfg(not(feature = "no_object"))] return Ok(self.value); #[cfg(feature = "no_object")] return self.type_error_str("map"); } } impl SerializeStruct for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_object"))] { let value = value.serialize(&mut *self)?; if let Some(map) = self.value.downcast_mut::() { map.insert(key.into(), value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_object")] self.type_error_str("map") } fn end(self) -> Result> { #[cfg(not(feature = "no_object"))] return Ok(self.value); #[cfg(feature = "no_object")] return self.type_error_str("map"); } } impl SerializeStructVariant for DynamicSerializer { type Ok = Dynamic; type Error = Box; fn serialize_field( &mut self, key: &'static str, value: &T, ) -> Result<(), Box> { #[cfg(not(feature = "no_object"))] { let value = value.serialize(&mut *self)?; if let Some(map) = self.value.downcast_mut::() { map.insert(key.into(), value); Ok(()) } else { self.type_error::() } } #[cfg(feature = "no_object")] self.type_error_str("map") } fn end(self) -> Result> { #[cfg(not(feature = "no_object"))] return Ok(self.value); #[cfg(feature = "no_object")] return self.type_error_str("map"); } }