Skip to main content

cgp_serde/providers/
extend.rs

1use cgp::prelude::*;
2use serde::de::{DeserializeSeed, Visitor};
3
4use crate::components::{CanDeserializeValue, ValueDeserializer, ValueDeserializerComponent};
5
6pub struct DeserializeExtend;
7
8#[cgp_impl(DeserializeExtend)]
9#[uses(CanDeserializeValue<'de, Item>)]
10impl<'de, Value, Item> ValueDeserializer<'de, Value>
11where
12    Value: Default + IntoIterator<Item = Item> + Extend<Item>,
13{
14    fn deserialize<D>(&self, deserializer: D) -> Result<Value, D::Error>
15    where
16        D: serde::Deserializer<'de>,
17    {
18        deserializer.deserialize_seq(DeserializeExtendVisitor {
19            context: self,
20            phantom: PhantomData,
21        })
22    }
23}
24
25struct DeserializeExtendVisitor<'a, Context, Value, Item> {
26    context: &'a Context,
27    phantom: PhantomData<(Value, Item)>,
28}
29
30impl<'de, 'a, Context, Value, Item> Visitor<'de>
31    for DeserializeExtendVisitor<'a, Context, Value, Item>
32where
33    Value: Default + Extend<Item>,
34    Context: CanDeserializeValue<'de, Item>,
35{
36    type Value = Value;
37
38    fn expecting(&self, formatter: &mut alloc::fmt::Formatter) -> alloc::fmt::Result {
39        write!(formatter, "sequence")
40    }
41
42    fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
43    where
44        A: serde::de::SeqAccess<'de>,
45    {
46        let mut value = Value::default();
47
48        while let Some(item) = seq.next_element_seed(DeserializeExtendSeed {
49            context: self.context,
50            phantom: PhantomData,
51        })? {
52            value.extend(core::iter::once(item));
53        }
54
55        Ok(value)
56    }
57}
58
59struct DeserializeExtendSeed<'a, Context, Item> {
60    context: &'a Context,
61    phantom: PhantomData<Item>,
62}
63
64impl<'de, 'a, Context, Item> DeserializeSeed<'de> for DeserializeExtendSeed<'a, Context, Item>
65where
66    Context: CanDeserializeValue<'de, Item>,
67{
68    type Value = Item;
69
70    fn deserialize<D>(self, deserializer: D) -> Result<Item, D::Error>
71    where
72        D: serde::Deserializer<'de>,
73    {
74        self.context.deserialize(deserializer)
75    }
76}