diff options
Diffstat (limited to 'vendor/toml_edit/src/de/table.rs')
-rw-r--r-- | vendor/toml_edit/src/de/table.rs | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/vendor/toml_edit/src/de/table.rs b/vendor/toml_edit/src/de/table.rs new file mode 100644 index 0000000..0b6183e --- /dev/null +++ b/vendor/toml_edit/src/de/table.rs @@ -0,0 +1,213 @@ +use serde::de::IntoDeserializer; + +use crate::de::Error; + +pub(crate) struct TableDeserializer { + span: Option<std::ops::Range<usize>>, + 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<V>(self, visitor: V) -> Result<V::Value, Self::Error> + 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<V>(self, visitor: V) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_some(self) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Error> + where + V: serde::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<V>( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + 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<crate::InternalString, crate::table::TableKeyValue>, + span: Option<std::ops::Range<usize>>, + 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<K>(&mut self, seed: K) -> Result<Option<K::Value>, 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<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + 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<V>(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)) + } +} |