serde_untagged/
seq.rs

1use crate::any::ErasedValue;
2use crate::error::{self, Error};
3use crate::seed::ErasedDeserializeSeed;
4use alloc::boxed::Box;
5use serde::de::{Deserialize, DeserializeSeed, SeqAccess};
6
7trait ErasedSeqAccess<'de> {
8    fn erased_next_element_seed(
9        &mut self,
10        seed: &mut dyn ErasedDeserializeSeed<'de>,
11    ) -> Result<Option<ErasedValue>, Error>;
12
13    fn erased_size_hint(&self) -> Option<usize>;
14}
15
16pub struct Seq<'access, 'de> {
17    erased: Box<dyn ErasedSeqAccess<'de> + 'access>,
18}
19
20impl<'access, 'de> Seq<'access, 'de> {
21    pub(crate) fn new<A>(seq: A) -> Self
22    where
23        A: SeqAccess<'de> + 'access,
24    {
25        Seq {
26            erased: Box::new(seq),
27        }
28    }
29
30    /// Shorthand for `T::deserialize(serde::de::value::SeqAccessDeserializer::new(self))`.
31    pub fn deserialize<T>(self) -> Result<T, Error>
32    where
33        T: Deserialize<'de>,
34    {
35        T::deserialize(serde::de::value::SeqAccessDeserializer::new(self))
36    }
37}
38
39impl<'access, 'de> SeqAccess<'de> for Seq<'access, 'de> {
40    type Error = Error;
41
42    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
43    where
44        T: DeserializeSeed<'de>,
45    {
46        self.erased
47            .erased_next_element_seed(&mut Some(seed))
48            .map(|erased_value| match erased_value {
49                Some(value) => Some(unsafe { ErasedValue::take::<T::Value>(value) }),
50                None => None,
51            })
52    }
53
54    fn size_hint(&self) -> Option<usize> {
55        self.erased.erased_size_hint()
56    }
57}
58
59impl<'de, Access> ErasedSeqAccess<'de> for Access
60where
61    Access: SeqAccess<'de>,
62{
63    fn erased_next_element_seed(
64        &mut self,
65        seed: &mut dyn ErasedDeserializeSeed<'de>,
66    ) -> Result<Option<ErasedValue>, Error> {
67        self.next_element_seed(seed).map_err(error::erase)
68    }
69
70    fn erased_size_hint(&self) -> Option<usize> {
71        self.size_hint()
72    }
73}