Skip to main content

step_p21/ast/de/
parameter.rs

1use super::*;
2use crate::ast::*;
3use inflector::Inflector;
4use serde::{
5    de::{self, IntoDeserializer},
6    forward_to_deserialize_any,
7};
8
9impl<'de> de::Deserializer<'de> for &Parameter {
10    type Error = crate::error::Error;
11
12    forward_to_deserialize_any! {
13        i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
14        bytes byte_buf unit unit_struct newtype_struct seq tuple
15        struct tuple_struct map enum identifier ignored_any
16    }
17
18    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
19    where
20        V: de::Visitor<'de>,
21    {
22        match self {
23            Parameter::Typed { keyword, parameter } => {
24                visitor.visit_map(RecordDeserializer::new(keyword, parameter))
25            }
26            Parameter::Integer(val) => visitor.visit_i64(*val),
27            Parameter::Real(val) => visitor.visit_f64(*val),
28            Parameter::String(val) => visitor.visit_str(val),
29            Parameter::List(params) => {
30                visitor.visit_seq(SeqDeserializer::new(params))
31            }
32            Parameter::Ref(name) => visitor.visit_enum(name),
33            Parameter::NotProvided | Parameter::Omitted => visitor.visit_none(),
34            Parameter::Enumeration(variant) => {
35                visitor.visit_enum(variant.to_pascal_case().into_deserializer())
36            }
37        }
38    }
39
40    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
41    where
42        V: de::Visitor<'de>,
43    {
44        if let Parameter::Enumeration(variant) = self {
45            match variant.as_str() {
46                "T" => visitor.visit_bool(true),
47                "TRUE" => visitor.visit_bool(true),
48                "F" => visitor.visit_bool(false),
49                "FALSE" => visitor.visit_bool(false),
50                _ => visitor
51                    .visit_enum(variant.to_pascal_case().into_deserializer()),
52            }
53        } else {
54            self.deserialize_any(visitor)
55        }
56    }
57
58    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
59    where
60        V: de::Visitor<'de>,
61    {
62        if matches!(self, Parameter::NotProvided | Parameter::Omitted) {
63            visitor.visit_none()
64        } else {
65            visitor.visit_some(self)
66        }
67    }
68}
69
70#[derive(Debug)]
71pub struct SeqDeserializer<'p> {
72    cursor: usize,
73    parameters: &'p [Parameter],
74}
75
76impl<'p> SeqDeserializer<'p> {
77    pub fn new(parameters: &'p [Parameter]) -> Self {
78        SeqDeserializer {
79            cursor: 0,
80            parameters,
81        }
82    }
83}
84
85impl<'de, 'p> de::Deserializer<'de> for SeqDeserializer<'p> {
86    type Error = crate::error::Error;
87
88    forward_to_deserialize_any! {
89        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
90        bytes byte_buf option unit unit_struct newtype_struct seq tuple
91        struct tuple_struct map enum identifier ignored_any
92    }
93
94    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
95    where
96        V: de::Visitor<'de>,
97    {
98        visitor.visit_seq(self)
99    }
100}
101
102impl<'de, 'p> de::SeqAccess<'de> for SeqDeserializer<'p> {
103    type Error = crate::error::Error;
104
105    fn size_hint(&self) -> Option<usize> {
106        Some(self.parameters.len())
107    }
108
109    fn next_element_seed<T>(
110        &mut self,
111        seed: T,
112    ) -> Result<Option<T::Value>, Self::Error>
113    where
114        T: de::DeserializeSeed<'de>,
115    {
116        if self.cursor < self.parameters.len() {
117            let value = seed.deserialize(&self.parameters[self.cursor])?;
118            self.cursor += 1;
119            Ok(Some(value))
120        } else {
121            Ok(None)
122        }
123    }
124}