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}