hcl/value/
de.rs

1use super::{Map, Value};
2use crate::{Error, Number, Result};
3use indexmap::map;
4use serde::de::{self, value::StringDeserializer, IntoDeserializer, Visitor};
5use serde::{forward_to_deserialize_any, Deserialize, Deserializer};
6use std::fmt;
7
8impl<'de> Deserialize<'de> for Value {
9    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
10    where
11        D: Deserializer<'de>,
12    {
13        struct ValueVisitor;
14
15        impl<'de> Visitor<'de> for ValueVisitor {
16            type Value = Value;
17
18            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
19                formatter.write_str("any valid HCL value")
20            }
21
22            fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
23                Ok(Value::Bool(value))
24            }
25
26            fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
27                Ok(Value::Number(value.into()))
28            }
29
30            fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
31                Ok(Value::Number(value.into()))
32            }
33
34            fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
35                Ok(Number::from_f64(value).map_or(Value::Null, Value::Number))
36            }
37
38            fn visit_str<E>(self, value: &str) -> Result<Value, E>
39            where
40                E: serde::de::Error,
41            {
42                self.visit_string(value.to_owned())
43            }
44
45            fn visit_string<E>(self, value: String) -> Result<Value, E> {
46                Ok(Value::String(value))
47            }
48
49            fn visit_none<E>(self) -> Result<Value, E> {
50                Ok(Value::Null)
51            }
52
53            fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
54            where
55                D: serde::Deserializer<'de>,
56            {
57                Deserialize::deserialize(deserializer)
58            }
59
60            fn visit_unit<E>(self) -> Result<Value, E> {
61                Ok(Value::Null)
62            }
63
64            fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
65            where
66                V: de::SeqAccess<'de>,
67            {
68                let mut vec = Vec::with_capacity(visitor.size_hint().unwrap_or(0));
69
70                while let Some(elem) = visitor.next_element()? {
71                    vec.push(elem);
72                }
73
74                Ok(Value::Array(vec))
75            }
76
77            fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
78            where
79                V: de::MapAccess<'de>,
80            {
81                let mut map = Map::with_capacity(visitor.size_hint().unwrap_or(0));
82
83                while let Some((key, value)) = visitor.next_entry()? {
84                    map.insert(key, value);
85                }
86
87                Ok(Value::Object(map))
88            }
89        }
90
91        deserializer.deserialize_any(ValueVisitor)
92    }
93}
94
95pub struct ValueDeserializer {
96    value: Value,
97}
98
99impl ValueDeserializer {
100    pub fn new(value: Value) -> ValueDeserializer {
101        ValueDeserializer { value }
102    }
103}
104
105impl IntoDeserializer<'_, Error> for Value {
106    type Deserializer = ValueDeserializer;
107
108    fn into_deserializer(self) -> Self::Deserializer {
109        ValueDeserializer { value: self }
110    }
111}
112
113impl<'de> de::Deserializer<'de> for ValueDeserializer {
114    type Error = Error;
115
116    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
117    where
118        V: de::Visitor<'de>,
119    {
120        match self.value {
121            Value::Null => visitor.visit_unit(),
122            Value::Bool(b) => visitor.visit_bool(b),
123            Value::Number(n) => n.deserialize_any(visitor).map_err(de::Error::custom),
124            Value::String(s) => visitor.visit_string(s),
125            Value::Array(array) => visitor.visit_seq(array.into_deserializer()),
126            Value::Object(object) => visitor.visit_map(object.into_deserializer()),
127        }
128    }
129
130    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
131    where
132        V: Visitor<'de>,
133    {
134        match self.value {
135            Value::Null => visitor.visit_none(),
136            _ => visitor.visit_some(self),
137        }
138    }
139
140    fn deserialize_enum<V>(
141        self,
142        _name: &'static str,
143        _variants: &'static [&'static str],
144        visitor: V,
145    ) -> Result<V::Value>
146    where
147        V: de::Visitor<'de>,
148    {
149        match self.value {
150            Value::String(s) => visitor.visit_enum(s.into_deserializer()),
151            Value::Object(object) => visitor.visit_enum(EnumAccess::new(object)),
152            _ => Err(de::Error::custom("expected an enum")),
153        }
154    }
155
156    forward_to_deserialize_any! {
157        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
158        bytes byte_buf unit unit_struct newtype_struct seq tuple
159        tuple_struct map struct identifier ignored_any
160    }
161}
162
163struct EnumAccess {
164    iter: map::IntoIter<String, Value>,
165}
166
167impl EnumAccess {
168    fn new(map: Map<String, Value>) -> Self {
169        EnumAccess {
170            iter: map.into_iter(),
171        }
172    }
173}
174
175impl<'de> de::EnumAccess<'de> for EnumAccess {
176    type Error = Error;
177    type Variant = VariantAccess;
178
179    fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant)>
180    where
181        V: de::DeserializeSeed<'de>,
182    {
183        match self.iter.next() {
184            Some((value, variant)) => Ok((
185                seed.deserialize::<StringDeserializer<Error>>(value.into_deserializer())?,
186                VariantAccess::new(variant),
187            )),
188            None => Err(de::Error::custom("expected an enum variant")),
189        }
190    }
191}
192
193struct VariantAccess {
194    value: Value,
195}
196
197impl VariantAccess {
198    fn new(value: Value) -> Self {
199        VariantAccess { value }
200    }
201}
202
203impl<'de> de::VariantAccess<'de> for VariantAccess {
204    type Error = Error;
205
206    fn unit_variant(self) -> Result<()> {
207        Err(de::Error::custom("expected a string"))
208    }
209
210    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
211    where
212        T: de::DeserializeSeed<'de>,
213    {
214        seed.deserialize(ValueDeserializer::new(self.value))
215    }
216
217    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
218    where
219        V: de::Visitor<'de>,
220    {
221        de::Deserializer::deserialize_seq(ValueDeserializer::new(self.value), visitor)
222    }
223
224    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
225    where
226        V: de::Visitor<'de>,
227    {
228        de::Deserializer::deserialize_map(ValueDeserializer::new(self.value), visitor)
229    }
230}