serde_untagged/
map.rs

1use crate::any::ErasedValue;
2use crate::error::{self, Error};
3use crate::seed::ErasedDeserializeSeed;
4use alloc::boxed::Box;
5use serde::de::{Deserialize, DeserializeSeed, MapAccess};
6
7trait ErasedMapAccess<'de> {
8    fn erased_next_key_seed(
9        &mut self,
10        seed: &mut dyn ErasedDeserializeSeed<'de>,
11    ) -> Result<Option<ErasedValue>, Error>;
12
13    fn erased_next_value_seed(
14        &mut self,
15        seed: &mut dyn ErasedDeserializeSeed<'de>,
16    ) -> Result<ErasedValue, Error>;
17
18    fn erased_size_hint(&self) -> Option<usize>;
19}
20
21pub struct Map<'access, 'de> {
22    erased: Box<dyn ErasedMapAccess<'de> + 'access>,
23}
24
25impl<'access, 'de> Map<'access, 'de> {
26    pub(crate) fn new<A>(map: A) -> Self
27    where
28        A: MapAccess<'de> + 'access,
29    {
30        Map {
31            erased: Box::new(map),
32        }
33    }
34
35    /// Shorthand for `T::deserialize(serde::de::value::MapAccessDeserializer::new(self))`.
36    pub fn deserialize<T>(self) -> Result<T, Error>
37    where
38        T: Deserialize<'de>,
39    {
40        T::deserialize(serde::de::value::MapAccessDeserializer::new(self))
41    }
42}
43
44impl<'access, 'de> MapAccess<'de> for Map<'access, 'de> {
45    type Error = Error;
46
47    fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
48    where
49        T: DeserializeSeed<'de>,
50    {
51        self.erased
52            .erased_next_key_seed(&mut Some(seed))
53            .map(|erased_value| match erased_value {
54                Some(value) => Some(unsafe { ErasedValue::take::<T::Value>(value) }),
55                None => None,
56            })
57    }
58
59    fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
60    where
61        T: DeserializeSeed<'de>,
62    {
63        self.erased
64            .erased_next_value_seed(&mut Some(seed))
65            .map(|erased_value| unsafe { ErasedValue::take::<T::Value>(erased_value) })
66    }
67
68    fn size_hint(&self) -> Option<usize> {
69        self.erased.erased_size_hint()
70    }
71}
72
73impl<'de, Access> ErasedMapAccess<'de> for Access
74where
75    Access: MapAccess<'de>,
76{
77    fn erased_next_key_seed(
78        &mut self,
79        seed: &mut dyn ErasedDeserializeSeed<'de>,
80    ) -> Result<Option<ErasedValue>, Error> {
81        self.next_key_seed(seed).map_err(error::erase)
82    }
83
84    fn erased_next_value_seed(
85        &mut self,
86        seed: &mut dyn ErasedDeserializeSeed<'de>,
87    ) -> Result<ErasedValue, Error> {
88        self.next_value_seed(seed).map_err(error::erase)
89    }
90
91    fn erased_size_hint(&self) -> Option<usize> {
92        self.size_hint()
93    }
94}