Augment builtin std/core Deserialize impls to implement deserialize_from
This commit is contained in:
parent
ab5e8780ab
commit
bc221abb04
@ -15,6 +15,7 @@ use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, Va
|
||||
use de::MapAccess;
|
||||
|
||||
use de::from_primitive::FromPrimitive;
|
||||
use private::de::DeserializeFromSeed;
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
use private::de::size_hint;
|
||||
@ -51,6 +52,7 @@ impl<'de> Deserialize<'de> for () {
|
||||
|
||||
struct BoolVisitor;
|
||||
|
||||
|
||||
impl<'de> Visitor<'de> for BoolVisitor {
|
||||
type Value = bool;
|
||||
|
||||
@ -210,6 +212,8 @@ impl<'de> Deserialize<'de> for char {
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
struct StringVisitor;
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
struct StringFromVisitor<'a>(&'a mut String);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'de> Visitor<'de> for StringVisitor {
|
||||
@ -254,6 +258,59 @@ impl<'de> Visitor<'de> for StringVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de> Visitor<'de> for StringFromVisitor<'a> {
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
self.0.clear();
|
||||
self.0.push_str(v);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
*self.0 = v;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
match str::from_utf8(v) {
|
||||
Ok(s) => {
|
||||
self.0.clear();
|
||||
self.0.push_str(s);
|
||||
Ok(())
|
||||
}
|
||||
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => {
|
||||
*self.0 = s;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'de> Deserialize<'de> for String {
|
||||
fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
|
||||
@ -262,6 +319,13 @@ impl<'de> Deserialize<'de> for String {
|
||||
{
|
||||
deserializer.deserialize_string(StringVisitor)
|
||||
}
|
||||
|
||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(StringFromVisitor(self))
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -421,6 +485,7 @@ forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
|
||||
struct OptionVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
struct OptionFromVisitor<'a, T: 'a>(&'a mut Option<T>);
|
||||
|
||||
impl<'de, T> Visitor<'de> for OptionVisitor<T>
|
||||
where
|
||||
@ -457,6 +522,49 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'de, T> Visitor<'de> for OptionFromVisitor<'a, T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("option")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
*self.0 = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_none<E>(self) -> Result<(), E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
*self.0 = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_some<D>(self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
// The some enum's repr is opaque, so we can't play cute tricks with
|
||||
// its tag to build this in place unconditionally.
|
||||
//
|
||||
// FIXME: investigate whether branching on the old value being Some to
|
||||
// deserialize_from the value is profitable (probably data-dependent?)
|
||||
*self.0 = try!(T::deserialize(deserializer).map(Some));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T> Deserialize<'de> for Option<T>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
@ -467,6 +575,13 @@ where
|
||||
{
|
||||
deserializer.deserialize_option(OptionVisitor { marker: PhantomData })
|
||||
}
|
||||
|
||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_option(OptionFromVisitor(self))
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -509,7 +624,9 @@ macro_rules! seq_impl {
|
||||
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
|
||||
$access:ident,
|
||||
$ctor:expr,
|
||||
$clear:expr,
|
||||
$with_capacity:expr,
|
||||
$reserve:expr,
|
||||
$insert:expr
|
||||
) => {
|
||||
impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty<T $(, $typaram)*>
|
||||
@ -554,16 +671,59 @@ macro_rules! seq_impl {
|
||||
let visitor = SeqVisitor { marker: PhantomData };
|
||||
deserializer.deserialize_seq(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct SeqVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
|
||||
|
||||
impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<'a, T $(, $typaram)*>
|
||||
where
|
||||
T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
|
||||
$($typaram: $bound1 $(+ $bound2)*,)*
|
||||
{
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
$clear(&mut self.0);
|
||||
$reserve(&mut self.0, size_hint::cautious($access.size_hint()));
|
||||
|
||||
// FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
|
||||
while let Some(value) = try!($access.next_element()) {
|
||||
$insert(&mut self.0, value);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_seq(SeqVisitor(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dummy impl of reserve
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
fn nop_reserve<T, U>(_x: T, _y: U) { }
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
seq_impl!(
|
||||
BinaryHeap<T: Ord>,
|
||||
seq,
|
||||
BinaryHeap::new(),
|
||||
BinaryHeap::clear,
|
||||
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||
BinaryHeap::reserve,
|
||||
BinaryHeap::push);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@ -571,7 +731,9 @@ seq_impl!(
|
||||
BTreeSet<T: Eq + Ord>,
|
||||
seq,
|
||||
BTreeSet::new(),
|
||||
BTreeSet::clear,
|
||||
BTreeSet::new(),
|
||||
nop_reserve,
|
||||
BTreeSet::insert);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@ -579,7 +741,9 @@ seq_impl!(
|
||||
LinkedList<T>,
|
||||
seq,
|
||||
LinkedList::new(),
|
||||
LinkedList::clear,
|
||||
LinkedList::new(),
|
||||
nop_reserve,
|
||||
LinkedList::push_back);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -587,7 +751,9 @@ seq_impl!(
|
||||
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
|
||||
seq,
|
||||
HashSet::with_hasher(S::default()),
|
||||
HashSet::clear,
|
||||
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
|
||||
HashSet::reserve,
|
||||
HashSet::insert);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@ -595,7 +761,9 @@ seq_impl!(
|
||||
Vec<T>,
|
||||
seq,
|
||||
Vec::new(),
|
||||
Vec::clear,
|
||||
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||
Vec::reserve,
|
||||
Vec::push);
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
@ -603,7 +771,9 @@ seq_impl!(
|
||||
VecDeque<T>,
|
||||
seq,
|
||||
VecDeque::new(),
|
||||
VecDeque::clear,
|
||||
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||
VecDeque::reserve,
|
||||
VecDeque::push_back);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -611,6 +781,7 @@ seq_impl!(
|
||||
struct ArrayVisitor<A> {
|
||||
marker: PhantomData<A>,
|
||||
}
|
||||
struct ArrayFromVisitor<'a, A: 'a>(&'a mut A);
|
||||
|
||||
impl<A> ArrayVisitor<A> {
|
||||
fn new() -> Self {
|
||||
@ -673,6 +844,35 @@ macro_rules! array_impls {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'de, T> Visitor<'de> for ArrayFromVisitor<'a, [T; $len]>
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("an array of length ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
let mut fail_idx = None;
|
||||
for (idx, dest) in self.0[..].iter_mut().enumerate() {
|
||||
if try!(seq.next_element_seed(DeserializeFromSeed(dest))).is_none() {
|
||||
fail_idx = Some(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(idx) = fail_idx {
|
||||
return Err(Error::invalid_length(idx, &self));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T> Deserialize<'de> for [T; $len]
|
||||
where
|
||||
T: Deserialize<'de>,
|
||||
@ -683,6 +883,13 @@ macro_rules! array_impls {
|
||||
{
|
||||
deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
|
||||
}
|
||||
|
||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_tuple($len, ArrayFromVisitor(self))
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
@ -726,49 +933,76 @@ array_impls! {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! tuple_impls {
|
||||
($($len:tt $visitor:ident => ($($n:tt $name:ident)+))+) => {
|
||||
($($len:tt => ($($n:tt $name:ident)+))+) => {
|
||||
$(
|
||||
struct $visitor<$($name,)+> {
|
||||
marker: PhantomData<($($name,)+)>,
|
||||
}
|
||||
|
||||
impl<$($name,)+> $visitor<$($name,)+> {
|
||||
fn new() -> Self {
|
||||
$visitor { marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for $visitor<$($name,)+> {
|
||||
type Value = ($($name,)+);
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("a tuple of size ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
$(
|
||||
let $name = match try!(seq.next_element()) {
|
||||
Some(value) => value,
|
||||
None => return Err(Error::invalid_length($n, &self)),
|
||||
};
|
||||
)+
|
||||
|
||||
Ok(($($name,)+))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_tuple($len, $visitor::new())
|
||||
struct TupleVisitor<$($name,)+> {
|
||||
marker: PhantomData<($($name,)+)>,
|
||||
}
|
||||
|
||||
impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
|
||||
type Value = ($($name,)+);
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("a tuple of size ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
$(
|
||||
let $name = match try!(seq.next_element()) {
|
||||
Some(value) => value,
|
||||
None => return Err(Error::invalid_length($n, &self)),
|
||||
};
|
||||
)+
|
||||
|
||||
Ok(($($name,)+))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct TupleVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
|
||||
|
||||
impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<'a, $($name,)+> {
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str(concat!("a tuple of size ", $len))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
$(
|
||||
if try!(seq.next_element_seed(DeserializeFromSeed(&mut (self.0).$n))).is_none() {
|
||||
return Err(Error::invalid_length($n, &self));
|
||||
}
|
||||
)+
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_tuple($len, TupleVisitor(self))
|
||||
}
|
||||
}
|
||||
)+
|
||||
@ -776,22 +1010,22 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
|
||||
tuple_impls! {
|
||||
1 TupleVisitor1 => (0 T0)
|
||||
2 TupleVisitor2 => (0 T0 1 T1)
|
||||
3 TupleVisitor3 => (0 T0 1 T1 2 T2)
|
||||
4 TupleVisitor4 => (0 T0 1 T1 2 T2 3 T3)
|
||||
5 TupleVisitor5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
|
||||
6 TupleVisitor6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
|
||||
7 TupleVisitor7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
|
||||
8 TupleVisitor8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
|
||||
9 TupleVisitor9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
|
||||
10 TupleVisitor10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
|
||||
11 TupleVisitor11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
|
||||
12 TupleVisitor12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
|
||||
13 TupleVisitor13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
|
||||
14 TupleVisitor14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
|
||||
15 TupleVisitor15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
|
||||
16 TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
|
||||
1 => (0 T0)
|
||||
2 => (0 T0 1 T1)
|
||||
3 => (0 T0 1 T1 2 T2)
|
||||
4 => (0 T0 1 T1 2 T2 3 T3)
|
||||
5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
|
||||
6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
|
||||
7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
|
||||
8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
|
||||
9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
|
||||
10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
|
||||
11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
|
||||
12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
|
||||
13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
|
||||
14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
|
||||
15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
|
||||
16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
use lib::*;
|
||||
|
||||
use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor};
|
||||
use de::{Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, Error, Visitor};
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
use de::Unexpected;
|
||||
@ -2009,3 +2009,20 @@ where
|
||||
map struct enum identifier ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
/// A DeserializeSeed helper for implementing deserialize_from Visitors.
|
||||
///
|
||||
/// Wraps a mutable reference and calls deserialize_from on it.
|
||||
pub struct DeserializeFromSeed<'a, T: 'a>(pub &'a mut T);
|
||||
|
||||
impl<'a, 'de, T> DeserializeSeed<'de> for DeserializeFromSeed<'a, T>
|
||||
where T: Deserialize<'de>,
|
||||
{
|
||||
type Value = ();
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
self.0.deserialize_from(deserializer)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user