Skip to main content

step_p21/ast/de/
subsuper.rs

1use crate::ast::*;
2use serde::{
3    de::{self, IntoDeserializer},
4    forward_to_deserialize_any,
5};
6
7impl<'de> de::Deserializer<'de> for &SubSuperRecord {
8    type Error = crate::error::Error;
9
10    forward_to_deserialize_any! {
11        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
12        bytes byte_buf option unit unit_struct newtype_struct seq tuple
13        struct tuple_struct map enum identifier ignored_any
14    }
15
16    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
17    where
18        V: de::Visitor<'de>,
19    {
20        visitor.visit_map(SubSuperRecordDeserializer::new(self.0.as_slice()))
21    }
22}
23
24#[derive(Debug)]
25pub struct SubSuperRecordDeserializer<'record> {
26    keywords: Vec<&'record str>,
27    parameters: Vec<&'record Parameter>,
28}
29
30impl<'record> SubSuperRecordDeserializer<'record> {
31    pub fn new(records: &'record [Record]) -> Self {
32        Self {
33            keywords: records.iter().map(|x| x.name.as_str()).collect(),
34            parameters: records.iter().map(|x| &x.parameter).collect(),
35        }
36    }
37}
38
39// Entry point of `visit_map`
40impl<'de, 'record> de::MapAccess<'de> for SubSuperRecordDeserializer<'record> {
41    type Error = crate::error::Error;
42
43    fn next_key_seed<K>(
44        &mut self,
45        seed: K,
46    ) -> Result<Option<K::Value>, Self::Error>
47    where
48        K: de::DeserializeSeed<'de>,
49    {
50        if let Some(key) = self.keywords.pop() {
51            let key: de::value::StrDeserializer<Self::Error> =
52                key.into_deserializer();
53            let key: K::Value = seed.deserialize(key)?;
54            Ok(Some(key))
55        } else {
56            Ok(None)
57        }
58    }
59
60    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
61    where
62        V: de::DeserializeSeed<'de>,
63    {
64        if let Some(value) = self.parameters.pop() {
65            let value: V::Value = seed.deserialize(value)?;
66            Ok(value)
67        } else {
68            unreachable!()
69        }
70    }
71}