//! Implementations of [`serde::Deserialize`]. use crate::{Dynamic, Identifier, ImmutableString, Scope, INT}; use serde::{ de::{Error, SeqAccess, Visitor}, Deserialize, Deserializer, }; use std::fmt; #[cfg(feature = "no_std")] use std::prelude::v1::*; struct DynamicVisitor; impl<'de> Visitor<'de> 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"))] { Ok(v.into()) } #[cfg(feature = "only_i32")] if v > i32::MAX as i64 { Ok(Dynamic::from(v)) } else { 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"))] { Ok(INT::from(v).into()) } #[cfg(feature = "only_i32")] if v > i32::MAX as u32 { Ok(Dynamic::from(v)) } else { 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 { Ok(Dynamic::from(v)) } else { self.visit_i64(v as i64) } #[cfg(feature = "only_i32")] if v > i32::MAX as u64 { Ok(Dynamic::from(v)) } else { self.visit_i32(v as i32) } } #[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); #[cfg(feature = "f32_float")] 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()); #[cfg(feature = "f32_float")] return self.visit_f32(v as f32); } #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] #[inline] fn visit_f32(self, v: f32) -> Result { use rust_decimal::Decimal; use std::convert::TryFrom; Decimal::try_from(v) .map(|v| v.into()) .map_err(Error::custom) } #[cfg(feature = "no_float")] #[cfg(feature = "decimal")] #[inline] fn visit_f64(self, v: f64) -> Result { use rust_decimal::Decimal; use std::convert::TryFrom; Decimal::try_from(v) .map(|v| v.into()) .map_err(Error::custom) } #[inline(always)] fn visit_char(self, v: char) -> Result { Ok(v.into()) } #[inline(always)] fn visit_str(self, v: &str) -> Result { Ok(v.into()) } #[inline(always)] fn visit_string(self, v: String) -> Result { Ok(v.into()) } #[inline(always)] fn visit_bytes(self, v: &[u8]) -> Result { Ok(Dynamic::from_blob(v.to_vec())) } #[inline(always)] fn visit_unit(self) -> Result { Ok(Dynamic::UNIT) } #[inline(always)] 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 = crate::Array::new(); 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 = crate::Map::new(); while let Some((k, v)) = map.next_entry()? { m.insert(k, v); } Ok(m.into()) } } impl<'de> Deserialize<'de> for Dynamic { #[inline(always)] fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_any(DynamicVisitor) } } impl<'de> Deserialize<'de> for ImmutableString { #[inline(always)] fn deserialize>(deserializer: D) -> Result { let s: String = Deserialize::deserialize(deserializer)?; Ok(s.into()) } } impl<'de> Deserialize<'de> for Scope<'de> { #[inline(always)] fn deserialize>(deserializer: D) -> Result { #[derive(Debug, Clone, Hash, Deserialize)] struct ScopeEntry { pub name: Identifier, pub value: Dynamic, #[serde(default)] pub is_constant: bool, } struct VecVisitor; impl<'de> Visitor<'de> for VecVisitor { type Value = Scope<'static>; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence") } #[inline] fn visit_seq(self, mut access: A) -> Result where A: SeqAccess<'de>, { let mut scope = match access.size_hint() { Some(size) => Scope::with_capacity(size), None => Scope::new(), }; while let Some(ScopeEntry { name, value, is_constant, }) = access.next_element()? { if is_constant { scope.push_constant_dynamic(name, value); } else { scope.push_dynamic(name, value); } } Ok(scope) } } deserializer.deserialize_seq(VecVisitor) } }