diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/de.rs | 56 |
1 files changed, 50 insertions, 6 deletions
@@ -8,6 +8,7 @@ use std::borrow::Cow; use std::error; use std::f64; use std::fmt; +use std::iter; use std::marker::PhantomData; use std::mem::discriminant; use std::str; @@ -216,7 +217,7 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> { let mut tables = self.tables()?; let res = visitor.visit_map(MapVisitor { - values: Vec::new().into_iter(), + values: Vec::new().into_iter().peekable(), next_value: None, depth: 0, cur: 0, @@ -333,7 +334,7 @@ struct Table<'a> { } struct MapVisitor<'de, 'b> { - values: vec::IntoIter<TablePair<'de>>, + values: iter::Peekable<vec::IntoIter<TablePair<'de>>>, next_value: Option<TablePair<'de>>, depth: usize, cur: usize, @@ -440,7 +441,8 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> { .values .take() .expect("Unable to read table values") - .into_iter(); + .into_iter() + .peekable(); } } @@ -462,7 +464,7 @@ impl<'de, 'b> de::MapAccess<'de> for MapVisitor<'de, 'b> { self.tables[self.cur].array && self.depth == self.tables[self.cur].header.len() - 1; self.cur += 1; let res = seed.deserialize(MapVisitor { - values: Vec::new().into_iter(), + values: Vec::new().into_iter().peekable(), next_value: None, depth: self.depth + if array { 0 } else { 1 }, cur_parent: self.cur - 1, @@ -509,7 +511,8 @@ impl<'de, 'b> de::SeqAccess<'de> for MapVisitor<'de, 'b> { .values .take() .expect("Unable to read table values") - .into_iter(), + .into_iter() + .peekable(), next_value: None, depth: self.depth + 1, cur_parent: self.cur_parent, @@ -558,6 +561,39 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> { visitor.visit_newtype_struct(self) } + fn deserialize_struct<V>( + mut self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Error> + where + V: de::Visitor<'de>, + { + if name == spanned::NAME + && fields == [spanned::START, spanned::END, spanned::VALUE] + && !(self.array && !self.values.peek().is_none()) + { + // TODO we can't actually emit spans here for the *entire* table/array + // due to the format that toml uses. Setting the start and end to 0 is + // *detectable* (and no reasonable span would look like that), + // it would be better to expose this in the API via proper + // ADTs like Option<T>. + let start = 0; + let end = 0; + + let res = visitor.visit_map(SpannedDeserializer { + phantom_data: PhantomData, + start: Some(start), + value: Some(self), + end: Some(end), + }); + return res; + } + + self.deserialize_any(visitor) + } + fn deserialize_enum<V>( self, _name: &'static str, @@ -591,7 +627,7 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> { serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq - bytes byte_buf map struct unit identifier + bytes byte_buf map unit identifier ignored_any unit_struct tuple_struct tuple } } @@ -853,6 +889,14 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> { } } +impl<'de, 'b> de::IntoDeserializer<'de, Error> for MapVisitor<'de, 'b> { + type Deserializer = MapVisitor<'de, 'b>; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + impl<'de, 'b> de::IntoDeserializer<'de, Error> for &'b mut Deserializer<'de> { type Deserializer = Self; |