use serde::de::IntoDeserializer; use crate::de::Error; pub(crate) struct TableDeserializer { span: Option>, items: crate::table::KeyValuePairs, } // Note: this is wrapped by `Deserializer` and `ValueDeserializer` and any trait methods // implemented here need to be wrapped there impl<'de> serde::Deserializer<'de> for TableDeserializer { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_map(crate::de::TableMapAccess::new(self)) } // `None` is interpreted as a missing field so be sure to implement `Some` // as a present field. fn deserialize_option(self, visitor: V) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_some(self) } fn deserialize_newtype_struct( self, _name: &'static str, visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { visitor.visit_newtype_struct(self) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { if serde_spanned::__unstable::is_spanned(name, fields) { if let Some(span) = self.span.clone() { return visitor.visit_map(super::SpannedDeserializer::new(self, span)); } } self.deserialize_any(visitor) } // Called when the type to deserialize is an enum, as opposed to a field in the type. fn deserialize_enum( self, _name: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { if self.items.is_empty() { Err(crate::de::Error::custom( "wanted exactly 1 element, found 0 elements", self.span, )) } else if self.items.len() != 1 { Err(crate::de::Error::custom( "wanted exactly 1 element, more than 1 element", self.span, )) } else { visitor.visit_enum(crate::de::TableMapAccess::new(self)) } } serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bytes byte_buf map unit ignored_any unit_struct tuple_struct tuple identifier } } impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for TableDeserializer { type Deserializer = TableDeserializer; fn into_deserializer(self) -> Self::Deserializer { self } } impl crate::Table { pub(crate) fn into_deserializer(self) -> TableDeserializer { TableDeserializer { span: self.span(), items: self.items, } } } impl crate::InlineTable { pub(crate) fn into_deserializer(self) -> TableDeserializer { TableDeserializer { span: self.span(), items: self.items, } } } pub(crate) struct TableMapAccess { iter: indexmap::map::IntoIter, span: Option>, value: Option<(crate::InternalString, crate::Item)>, } impl TableMapAccess { pub(crate) fn new(input: TableDeserializer) -> Self { Self { iter: input.items.into_iter(), span: input.span, value: None, } } } impl<'de> serde::de::MapAccess<'de> for TableMapAccess { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> where K: serde::de::DeserializeSeed<'de>, { match self.iter.next() { Some((k, v)) => { let ret = seed .deserialize(super::KeyDeserializer::new(k, v.key.span())) .map(Some) .map_err(|mut e: Self::Error| { if e.span().is_none() { e.set_span(v.key.span()); } e }); self.value = Some((v.key.into(), v.value)); ret } None => Ok(None), } } fn next_value_seed(&mut self, seed: V) -> Result where V: serde::de::DeserializeSeed<'de>, { match self.value.take() { Some((k, v)) => { let span = v.span(); seed.deserialize(crate::de::ValueDeserializer::new(v)) .map_err(|mut e: Self::Error| { if e.span().is_none() { e.set_span(span); } e.add_key(k.as_str().to_owned()); e }) } None => { panic!("no more values in next_value_seed, internal error in ValueDeserializer") } } } } impl<'de> serde::de::EnumAccess<'de> for TableMapAccess { type Error = Error; type Variant = super::TableEnumDeserializer; fn variant_seed(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> where V: serde::de::DeserializeSeed<'de>, { let (key, value) = match self.iter.next() { Some(pair) => pair, None => { return Err(Error::custom( "expected table with exactly 1 entry, found empty table", self.span, )); } }; let val = seed .deserialize(key.into_deserializer()) .map_err(|mut e: Self::Error| { if e.span().is_none() { e.set_span(value.key.span()); } e })?; let variant = super::TableEnumDeserializer::new(value.value); Ok((val, variant)) } }