serde_dhall/
deserialize.rs1use std::borrow::Cow;
2use std::collections::BTreeMap;
3use std::fmt;
4
5use serde::de::value::{
6 MapAccessDeserializer, MapDeserializer, SeqDeserializer,
7};
8use serde::de::VariantAccess as _;
9
10use dhall::syntax::NumKind;
11
12use crate::value::SimpleValue;
13use crate::{Error, ErrorKind, Value};
14
15pub trait Sealed {}
16
17pub trait FromDhall: Sealed + Sized {
44 #[doc(hidden)]
45 fn from_dhall(v: &Value) -> crate::Result<Self>;
46}
47
48impl<T> Sealed for T where T: serde::de::DeserializeOwned {}
49
50pub fn from_simple_value<T>(v: SimpleValue) -> crate::Result<T>
88where
89 T: serde::de::DeserializeOwned,
90{
91 T::deserialize(Deserializer(Cow::Owned(v)))
92}
93
94impl<T> FromDhall for T
95where
96 T: serde::de::DeserializeOwned,
97{
98 fn from_dhall(v: &Value) -> crate::Result<Self> {
99 let sval = v.to_simple_value().ok_or_else(|| {
100 Error(ErrorKind::Deserialize(format!(
101 "this cannot be deserialized into the serde data model: {}",
102 v
103 )))
104 })?;
105 from_simple_value(sval)
106 }
107}
108
109struct Deserializer<'a>(Cow<'a, SimpleValue>);
110
111impl<'de: 'a, 'a> serde::de::IntoDeserializer<'de, Error> for Deserializer<'a> {
112 type Deserializer = Deserializer<'a>;
113 fn into_deserializer(self) -> Self::Deserializer {
114 self
115 }
116}
117
118impl<'de: 'a, 'a> serde::Deserializer<'de> for Deserializer<'a> {
119 type Error = Error;
120
121 fn deserialize_any<V>(self, visitor: V) -> crate::Result<V::Value>
122 where
123 V: serde::de::Visitor<'de>,
124 {
125 use NumKind::*;
126 use SimpleValue::*;
127
128 let val = |x| Deserializer(Cow::Borrowed(x));
129 match self.0.as_ref() {
130 Num(Bool(x)) => visitor.visit_bool(*x),
131 Num(Natural(x)) => visitor.visit_u64(*x),
132 Num(Integer(x)) => visitor.visit_i64(*x),
133 Num(Double(x)) => visitor.visit_f64((*x).into()),
134 Text(x) => visitor.visit_str(x),
135 List(xs) => {
136 visitor.visit_seq(SeqDeserializer::new(xs.iter().map(val)))
137 }
138 Optional(None) => visitor.visit_none(),
139 Optional(Some(x)) => visitor.visit_some(val(x)),
140 Record(m) => visitor.visit_map(MapDeserializer::new(
141 m.iter().map(|(k, v)| (k.as_str(), val(v))),
142 )),
143 Union(field_name, Some(x)) => visitor.visit_enum(
144 MapAccessDeserializer::new(MapDeserializer::new(
145 Some((field_name.as_str(), val(x))).into_iter(),
146 )),
147 ),
148 Union(field_name, None) => visitor.visit_enum(
149 MapAccessDeserializer::new(MapDeserializer::new(
150 Some((field_name.as_str(), ())).into_iter(),
151 )),
152 ),
153 }
154 }
155
156 fn deserialize_tuple<V>(
157 self,
158 _: usize,
159 visitor: V,
160 ) -> crate::Result<V::Value>
161 where
162 V: serde::de::Visitor<'de>,
163 {
164 let val = |x| Deserializer(Cow::Borrowed(x));
165 match self.0.as_ref() {
166 SimpleValue::Record(m) => visitor
168 .visit_seq(SeqDeserializer::new(m.iter().map(|(_, v)| val(v)))),
169 _ => self.deserialize_any(visitor),
170 }
171 }
172
173 fn deserialize_unit<V>(self, visitor: V) -> crate::Result<V::Value>
174 where
175 V: serde::de::Visitor<'de>,
176 {
177 match self.0.as_ref() {
178 SimpleValue::Record(m) if m.is_empty() => visitor.visit_unit(),
179 _ => self.deserialize_any(visitor),
180 }
181 }
182
183 serde::forward_to_deserialize_any! {
184 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
185 bytes byte_buf option unit_struct newtype_struct seq
186 tuple_struct map struct enum identifier ignored_any
187 }
188}
189
190struct SimpleValueVisitor;
191
192impl<'de> serde::de::Visitor<'de> for SimpleValueVisitor {
193 type Value = SimpleValue;
194
195 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
196 formatter.write_str("any valid Dhall value")
197 }
198
199 fn visit_bool<E>(self, value: bool) -> Result<SimpleValue, E> {
200 Ok(SimpleValue::Num(NumKind::Bool(value)))
201 }
202
203 fn visit_i64<E>(self, value: i64) -> Result<SimpleValue, E> {
204 Ok(SimpleValue::Num(NumKind::Integer(value)))
205 }
206
207 fn visit_u64<E>(self, value: u64) -> Result<SimpleValue, E> {
208 Ok(SimpleValue::Num(NumKind::Natural(value)))
209 }
210
211 fn visit_f64<E>(self, value: f64) -> Result<SimpleValue, E> {
212 Ok(SimpleValue::Num(NumKind::Double(value.into())))
213 }
214
215 fn visit_str<E>(self, value: &str) -> Result<SimpleValue, E> {
216 Ok(SimpleValue::Text(String::from(value)))
217 }
218
219 fn visit_string<E>(self, value: String) -> Result<SimpleValue, E> {
220 Ok(SimpleValue::Text(value))
221 }
222
223 fn visit_none<E>(self) -> Result<SimpleValue, E> {
224 Ok(SimpleValue::Optional(None))
225 }
226
227 fn visit_some<D>(self, val: D) -> Result<SimpleValue, D::Error>
228 where
229 D: serde::Deserializer<'de>,
230 {
231 let val = val.deserialize_any(SimpleValueVisitor)?;
232 Ok(SimpleValue::Optional(Some(Box::new(val))))
233 }
234
235 fn visit_enum<V>(self, visitor: V) -> Result<SimpleValue, V::Error>
236 where
237 V: serde::de::EnumAccess<'de>,
238 {
239 let (name, variant): (String, _) = visitor.variant()?;
240 let val = variant.newtype_variant().ok();
245 Ok(SimpleValue::Union(name, val))
246 }
247
248 fn visit_seq<V>(self, mut visitor: V) -> Result<SimpleValue, V::Error>
249 where
250 V: serde::de::SeqAccess<'de>,
251 {
252 let mut vec = Vec::new();
253 while let Some(elem) = visitor.next_element()? {
254 vec.push(elem);
255 }
256 Ok(SimpleValue::List(vec))
257 }
258
259 fn visit_map<V>(self, mut visitor: V) -> Result<SimpleValue, V::Error>
260 where
261 V: serde::de::MapAccess<'de>,
262 {
263 let mut record = BTreeMap::default();
264 while let Some((key, value)) = visitor.next_entry()? {
265 record.insert(key, value);
266 }
267 Ok(SimpleValue::Record(record))
268 }
269}
270
271impl<'de> serde::de::Deserialize<'de> for SimpleValue {
272 fn deserialize<D>(deserializer: D) -> Result<SimpleValue, D::Error>
273 where
274 D: serde::Deserializer<'de>,
275 {
276 deserializer.deserialize_any(SimpleValueVisitor)
277 }
278}