//! Implementations of [`serde::Deserialize`]. use crate::stdlib::{fmt, string::ToString}; use crate::{Dynamic, ImmutableString, INT}; use serde::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; #[cfg(not(feature = "no_index"))] use crate::Array; #[cfg(not(feature = "no_object"))] use crate::Map; struct DynamicVisitor; impl<'d> Visitor<'d> for DynamicVisitor { type Value = Dynamic; fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("any type that can be converted into a Dynamic") } fn visit_bool(self, v: bool) -> Result { Ok(v.into()) } fn visit_i8(self, v: i8) -> Result { Ok(INT::from(v).into()) } fn visit_i16(self, v: i16) -> Result { Ok(INT::from(v).into()) } fn visit_i32(self, v: i32) -> Result { Ok(INT::from(v).into()) } fn visit_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.visit_i32(v as i32); } } fn visit_u8(self, v: u8) -> Result { Ok(INT::from(v).into()) } fn visit_u16(self, v: u16) -> Result { Ok(INT::from(v).into()) } fn visit_u32(self, v: u32) -> Result { #[cfg(not(feature = "only_i32"))] return Ok(INT::from(v).into()); #[cfg(feature = "only_i32")] if v > i32::MAX as u32 { return Ok(Dynamic::from(v)); } else { return self.visit_i32(v as i32); } } fn visit_u64(self, v: u64) -> Result { #[cfg(not(feature = "only_i32"))] if v > i64::MAX as u64 { return Ok(Dynamic::from(v)); } else { return self.visit_i64(v as i64); } #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { return Ok(Dynamic::from(v)); } else { return self.visit_i32(v as i32); } } #[cfg(not(feature = "no_float"))] fn visit_f32(self, v: f32) -> Result { #[cfg(not(feature = "f32_float"))] return self.visit_f64(v as f64); #[cfg(feature = "f32_float")] return Ok(v.into()); } #[cfg(not(feature = "no_float"))] fn visit_f64(self, v: f64) -> Result { #[cfg(not(feature = "f32_float"))] return Ok(v.into()); #[cfg(feature = "f32_float")] return self.visit_f32(v as f32); } #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] fn visit_f32(self, v: f32) -> Result { use crate::stdlib::convert::TryFrom; use rust_decimal::Decimal; Decimal::try_from(v) .map(|v| v.into()) .map_err(Error::custom) } #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] fn visit_f64(self, v: f64) -> Result { use crate::stdlib::convert::TryFrom; use rust_decimal::Decimal; Decimal::try_from(v) .map(|v| v.into()) .map_err(Error::custom) } fn visit_char(self, v: char) -> Result { self.visit_string(v.to_string()) } fn visit_str(self, v: &str) -> Result { Ok(v.into()) } fn visit_borrowed_str(self, v: &str) -> Result { self.visit_str(v) } fn visit_string(self, v: String) -> Result { Ok(v.into()) } fn visit_unit(self) -> Result { Ok(Dynamic::UNIT) } fn visit_newtype_struct>(self, de: D) -> Result { Deserialize::deserialize(de) } #[cfg(not(feature = "no_index"))] fn visit_seq>(self, mut seq: A) -> Result { let mut arr: Array = Default::default(); while let Some(v) = seq.next_element()? { arr.push(v); } Ok(arr.into()) } #[cfg(not(feature = "no_object"))] fn visit_map>(self, mut map: M) -> Result { let mut m: Map = Default::default(); while let Some((k, v)) = map.next_entry()? { m.insert(k, v); } Ok(m.into()) } } impl<'d> Deserialize<'d> for Dynamic { fn deserialize>(de: D) -> Result { de.deserialize_any(DynamicVisitor) } } impl<'d> Deserialize<'d> for ImmutableString { fn deserialize>(de: D) -> Result { let s: String = Deserialize::deserialize(de)?; Ok(s.into()) } }