diff options
author | est31 <est31@users.noreply.github.com> | 2019-09-05 15:38:54 +0200 |
---|---|---|
committer | Alex Crichton <alex@alexcrichton.com> | 2019-09-05 08:38:54 -0500 |
commit | 6bbafa448922791d54ee253a7a725d4033071c3c (patch) | |
tree | 60eab8d2d8b965f3f8154c48913429de47e2bb45 /src | |
parent | b2a427ee7df39d27e86348fbb3f4e79cf2074d41 (diff) | |
download | milf-rs-6bbafa448922791d54ee253a7a725d4033071c3c.tar.gz milf-rs-6bbafa448922791d54ee253a7a725d4033071c3c.zip |
Suppport deserialization of Spanned<> at the top level (#328)
Diffstat (limited to 'src')
-rw-r--r-- | src/de.rs | 47 |
1 files changed, 43 insertions, 4 deletions
@@ -8,6 +8,7 @@ use std::borrow::Cow; use std::error; use std::f64; use std::fmt; +use std::marker::PhantomData; use std::mem::discriminant; use std::str; use std::vec; @@ -285,9 +286,34 @@ impl<'de, 'b> de::Deserializer<'de> for &'b mut Deserializer<'de> { } } + fn deserialize_struct<V>( + 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] { + let start = 0; + let end = self.input.len(); + + let res = visitor.visit_map(SpannedDeserializer { + phantom_data: PhantomData, + start: Some(start), + value: Some(self), + end: Some(end), + }); + return res; + } + + self.deserialize_any(visitor) + } + 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 newtype_struct + bytes byte_buf map unit newtype_struct ignored_any unit_struct tuple_struct tuple option identifier } } @@ -664,6 +690,7 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> { let end = self.value.end; return visitor.visit_map(SpannedDeserializer { + phantom_data: PhantomData, start: Some(start), value: Some(self.value), end: Some(end), @@ -741,6 +768,14 @@ impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> { } } +impl<'de, 'b> de::IntoDeserializer<'de, Error> for &'b mut Deserializer<'de> { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + impl<'de> de::IntoDeserializer<'de, Error> for Value<'de> { type Deserializer = ValueDeserializer<'de>; @@ -749,13 +784,17 @@ impl<'de> de::IntoDeserializer<'de, Error> for Value<'de> { } } -struct SpannedDeserializer<'a> { +struct SpannedDeserializer<'de, T: de::IntoDeserializer<'de, Error>> { + phantom_data: PhantomData<&'de ()>, start: Option<usize>, end: Option<usize>, - value: Option<Value<'a>>, + value: Option<T>, } -impl<'de> de::MapAccess<'de> for SpannedDeserializer<'de> { +impl<'de, T> de::MapAccess<'de> for SpannedDeserializer<'de, T> +where + T: de::IntoDeserializer<'de, Error>, +{ type Error = Error; fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> |