hmap_serde/hmap/
de.rs

1use std::fmt::Formatter;
2use std::marker::PhantomData;
3
4use frunk_core::hlist::{HCons, HList, HNil};
5use frunk_core::traits::IntoReverse;
6use serde::de::{MapAccess, Visitor};
7use serde::{Deserialize, Deserializer};
8
9use super::HMap;
10
11struct HMapVisitor<L>(PhantomData<L>);
12
13impl<L> Default for HMapVisitor<L> {
14    fn default() -> Self {
15        Self(PhantomData)
16    }
17}
18
19impl<'de, L> Visitor<'de> for HMapVisitor<L>
20where
21    L: IntoReverse,
22    L::Output: MapDeserializable<'de> + IntoReverse<Output = L>,
23{
24    type Value = HMap<L>;
25
26    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
27        formatter.write_str("a heterogeneous map")
28    }
29
30    fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
31    where
32        A: MapAccess<'de>,
33    {
34        let (reversed, _) = <L::Output as MapDeserializable<'de>>::visit_map(map)?;
35        Ok(HMap(reversed.into_reverse()))
36    }
37}
38
39pub trait MapDeserializable<'de>: HList {
40    fn visit_map<A: MapAccess<'de>>(map: A) -> Result<(Self, A), A::Error>;
41}
42
43impl<'de, K, V, T> MapDeserializable<'de> for HCons<(K, V), T>
44where
45    K: Deserialize<'de>,
46    V: Deserialize<'de>,
47    T: MapDeserializable<'de>,
48{
49    fn visit_map<A: MapAccess<'de>>(map: A) -> Result<(Self, A), A::Error> {
50        let (append, mut map) = T::visit_map(map)?;
51        let (k, v) = map.next_entry()?.expect("unexpected eof");
52        Ok((append.prepend((k, v)), map))
53    }
54}
55
56impl<'de> MapDeserializable<'de> for HNil {
57    fn visit_map<A: MapAccess<'de>>(map: A) -> Result<(Self, A), A::Error> {
58        Ok((HNil, map))
59    }
60}
61
62impl<'de, L> Deserialize<'de> for HMap<L>
63where
64    L: IntoReverse,
65    L::Output: MapDeserializable<'de> + IntoReverse<Output = L>,
66{
67    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68    where
69        D: Deserializer<'de>,
70    {
71        deserializer.deserialize_map(HMapVisitor::default())
72    }
73}