1use std::ops::{Deref, DerefMut};
2
3use serde::de::value::{MapDeserializer, SeqDeserializer};
4use serde::de::{
5 self, Deserialize, DeserializeOwned, DeserializeSeed, Deserializer, EnumAccess,
6 IntoDeserializer, MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor,
7};
8use serde::forward_to_deserialize_any;
9
10use crate::value::{ArgType, ObjectRepr, Value, ValueKind, ValueMap, ValueRepr};
11use crate::{Error, ErrorKind};
12
13#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
14impl<'de> Deserialize<'de> for Value {
15 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
16 deserializer.deserialize_any(ValueVisitor)
17 }
18}
19
20struct ValueVisitor;
21
22macro_rules! visit_value_primitive {
23 ($name:ident, $ty:ty) => {
24 fn $name<E: de::Error>(self, v: $ty) -> Result<Value, E> {
25 Ok(Value::from(v))
26 }
27 };
28}
29
30impl<'de> Visitor<'de> for ValueVisitor {
31 type Value = Value;
32
33 fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
34 fmt.write_str("any MiniJinja compatible value")
35 }
36
37 visit_value_primitive!(visit_bool, bool);
38 visit_value_primitive!(visit_i8, i8);
39 visit_value_primitive!(visit_i16, i16);
40 visit_value_primitive!(visit_i32, i32);
41 visit_value_primitive!(visit_i64, i64);
42 visit_value_primitive!(visit_i128, i128);
43 visit_value_primitive!(visit_u16, u16);
44 visit_value_primitive!(visit_u32, u32);
45 visit_value_primitive!(visit_u64, u64);
46 visit_value_primitive!(visit_u128, u128);
47 visit_value_primitive!(visit_f32, f32);
48 visit_value_primitive!(visit_f64, f64);
49 visit_value_primitive!(visit_char, char);
50 visit_value_primitive!(visit_str, &str);
51 visit_value_primitive!(visit_string, String);
52 visit_value_primitive!(visit_bytes, &[u8]);
53 visit_value_primitive!(visit_byte_buf, Vec<u8>);
54
55 fn visit_none<E: de::Error>(self) -> Result<Value, E> {
56 Ok(Value::from(()))
57 }
58
59 fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Value, D::Error> {
60 Deserialize::deserialize(deserializer)
61 }
62
63 fn visit_unit<E: de::Error>(self) -> Result<Value, E> {
64 Ok(Value::from(()))
65 }
66
67 fn visit_newtype_struct<D: Deserializer<'de>>(
68 self,
69 deserializer: D,
70 ) -> Result<Value, D::Error> {
71 Deserialize::deserialize(deserializer)
72 }
73
74 fn visit_seq<A: SeqAccess<'de>>(self, mut visitor: A) -> Result<Value, A::Error> {
75 let mut rv = Vec::<Value>::new();
76 while let Some(e) = ok!(visitor.next_element()) {
77 rv.push(e);
78 }
79 Ok(Value::from(rv))
80 }
81
82 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Value, A::Error> {
83 let mut rv = ValueMap::default();
84 while let Some((k, v)) = ok!(map.next_entry()) {
85 rv.insert(k, v);
86 }
87 Ok(Value::from_object(rv))
88 }
89}
90
91#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
113pub struct ViaDeserialize<T: DeserializeOwned>(pub T);
114
115impl<'a, T: DeserializeOwned> ArgType<'a> for ViaDeserialize<T> {
116 type Output = Self;
117
118 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
119 match value {
120 Some(value) => {
121 if value.is_kwargs() {
122 return Err(Error::new(
123 ErrorKind::InvalidOperation,
124 "cannot deserialize from kwargs",
125 ));
126 }
127 T::deserialize(value).map(ViaDeserialize)
128 }
129 None => Err(Error::from(ErrorKind::MissingArgument)),
130 }
131 }
132}
133
134impl<T: DeserializeOwned> Deref for ViaDeserialize<T> {
135 type Target = T;
136
137 fn deref(&self) -> &T {
138 &self.0
139 }
140}
141
142impl<T: DeserializeOwned> DerefMut for ViaDeserialize<T> {
143 fn deref_mut(&mut self) -> &mut T {
144 &mut self.0
145 }
146}
147
148macro_rules! common_forward {
151 () => {
152 forward_to_deserialize_any! {
153 bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit
154 seq bytes byte_buf map
155 tuple_struct struct tuple ignored_any identifier
156 }
157 };
158}
159
160#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
161impl IntoDeserializer<'_, Error> for Value {
162 type Deserializer = Value;
163
164 fn into_deserializer(self) -> Value {
165 self
166 }
167}
168
169#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
170impl<'de> Deserializer<'de> for Value {
171 type Error = Error;
172
173 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
174 match self.0 {
175 ValueRepr::Invalid(ref error) => Err(de::Error::custom(error)),
176 ValueRepr::Bool(v) => visitor.visit_bool(v),
177 ValueRepr::U64(v) => visitor.visit_u64(v),
178 ValueRepr::I64(v) => visitor.visit_i64(v),
179 ValueRepr::I128(v) => visitor.visit_i128(v.0),
180 ValueRepr::U128(v) => visitor.visit_u128(v.0),
181 ValueRepr::F64(v) => visitor.visit_f64(v),
182 ValueRepr::String(ref v, _) => visitor.visit_str(v),
183 ValueRepr::SmallStr(v) => visitor.visit_str(v.as_str()),
184 ValueRepr::Undefined(_) | ValueRepr::None => visitor.visit_unit(),
185 ValueRepr::Bytes(ref v) => visitor.visit_bytes(v),
186 ValueRepr::Object(o) => match o.repr() {
187 ObjectRepr::Plain => Err(de::Error::custom("cannot deserialize plain objects")),
188 ObjectRepr::Seq | ObjectRepr::Iterable => {
189 visitor.visit_seq(SeqDeserializer::new(o.try_iter().into_iter().flatten()))
190 }
191 ObjectRepr::Map => visitor.visit_map(MapDeserializer::new(
192 o.try_iter_pairs().into_iter().flatten(),
193 )),
194 },
195 }
196 }
197
198 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
199 match self.0 {
200 ValueRepr::None | ValueRepr::Undefined(_) => visitor.visit_unit(),
201 _ => visitor.visit_some(self),
202 }
203 }
204
205 fn deserialize_enum<V: Visitor<'de>>(
206 self,
207 _name: &'static str,
208 _variants: &'static [&'static str],
209 visitor: V,
210 ) -> Result<V::Value, Error> {
211 let (variant, value) = match self.kind() {
212 ValueKind::Map => {
213 let mut iter = ok!(self.try_iter());
214 let variant = match iter.next() {
215 Some(v) => v,
216 None => {
217 return Err(de::Error::invalid_value(
218 Unexpected::Map,
219 &"map with a single key",
220 ))
221 }
222 };
223 if iter.next().is_some() {
224 return Err(de::Error::invalid_value(
225 Unexpected::Map,
226 &"map with a single key",
227 ));
228 }
229 let val = self.get_item_opt(&variant);
230 (variant, val)
231 }
232 ValueKind::String => (self, None),
233 _ => {
234 return Err(de::Error::invalid_type(
235 value_to_unexpected(&self),
236 &"string or map",
237 ))
238 }
239 };
240
241 visitor.visit_enum(EnumDeserializer { variant, value })
242 }
243
244 #[inline]
245 fn deserialize_unit_struct<V: Visitor<'de>>(
246 self,
247 _name: &'static str,
248 visitor: V,
249 ) -> Result<V::Value, Error> {
250 self.deserialize_unit(visitor)
251 }
252
253 #[inline]
254 fn deserialize_newtype_struct<V: Visitor<'de>>(
255 self,
256 _name: &'static str,
257 visitor: V,
258 ) -> Result<V::Value, Error> {
259 visitor.visit_newtype_struct(self)
260 }
261
262 common_forward!();
263}
264
265struct EnumDeserializer {
266 variant: Value,
267 value: Option<Value>,
268}
269
270impl<'de> EnumAccess<'de> for EnumDeserializer {
271 type Error = Error;
272 type Variant = VariantDeserializer;
273
274 fn variant_seed<V: DeserializeSeed<'de>>(
275 self,
276 seed: V,
277 ) -> Result<(V::Value, VariantDeserializer), Error> {
278 seed.deserialize(self.variant)
279 .map(|v| (v, VariantDeserializer { value: self.value }))
280 }
281}
282
283struct VariantDeserializer {
284 value: Option<Value>,
285}
286
287impl<'de> VariantAccess<'de> for VariantDeserializer {
288 type Error = Error;
289
290 fn unit_variant(self) -> Result<(), Error> {
291 match self.value {
292 Some(value) => Deserialize::deserialize(value),
293 None => Ok(()),
294 }
295 }
296
297 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value, Error> {
298 match self.value {
299 Some(value) => seed.deserialize(value),
300 None => Err(de::Error::invalid_type(
301 Unexpected::UnitVariant,
302 &"newtype variant",
303 )),
304 }
305 }
306
307 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Error> {
308 match self.value.as_ref().and_then(|x| x.as_object()) {
309 Some(obj) if matches!(obj.repr(), ObjectRepr::Seq) => Deserializer::deserialize_any(
310 SeqDeserializer::new(obj.try_iter().into_iter().flatten()),
311 visitor,
312 ),
313 _ => Err(de::Error::invalid_type(
314 self.value
315 .as_ref()
316 .map_or(Unexpected::Unit, value_to_unexpected),
317 &"tuple variant",
318 )),
319 }
320 }
321
322 fn struct_variant<V: Visitor<'de>>(
323 self,
324 _fields: &'static [&'static str],
325 visitor: V,
326 ) -> Result<V::Value, Error> {
327 match self.value.as_ref().map(|x| (x.kind(), x)) {
328 Some((ValueKind::Map, val)) => Deserializer::deserialize_any(
329 MapDeserializer::new(
330 ok!(val.try_iter())
331 .map(|ref k| (k.clone(), val.get_item(k).unwrap_or_default())),
332 ),
333 visitor,
334 ),
335 _ => Err(de::Error::invalid_type(
336 self.value
337 .as_ref()
338 .map_or(Unexpected::Unit, value_to_unexpected),
339 &"struct variant",
340 )),
341 }
342 }
343}
344
345#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
346impl<'de> Deserializer<'de> for &Value {
347 type Error = Error;
348
349 #[inline]
350 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
351 self.clone().deserialize_any(visitor)
352 }
353
354 #[inline]
355 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Error> {
356 self.clone().deserialize_option(visitor)
357 }
358
359 #[inline]
360 fn deserialize_enum<V: Visitor<'de>>(
361 self,
362 name: &'static str,
363 variants: &'static [&'static str],
364 visitor: V,
365 ) -> Result<V::Value, Error> {
366 self.clone().deserialize_enum(name, variants, visitor)
367 }
368
369 #[inline]
370 fn deserialize_unit_struct<V: Visitor<'de>>(
371 self,
372 name: &'static str,
373 visitor: V,
374 ) -> Result<V::Value, Error> {
375 self.clone().deserialize_unit_struct(name, visitor)
376 }
377
378 #[inline]
379 fn deserialize_newtype_struct<V: Visitor<'de>>(
380 self,
381 name: &'static str,
382 visitor: V,
383 ) -> Result<V::Value, Error> {
384 self.clone().deserialize_newtype_struct(name, visitor)
385 }
386
387 common_forward!();
388}
389
390#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
391impl<'de> IntoDeserializer<'de, Error> for &'de Value {
392 type Deserializer = &'de Value;
393
394 fn into_deserializer(self) -> &'de Value {
395 self
396 }
397}
398
399#[cfg_attr(docsrs, doc(cfg(feature = "deserialization")))]
400impl de::Error for Error {
401 fn custom<T: std::fmt::Display>(msg: T) -> Self {
402 Error::new(ErrorKind::CannotDeserialize, msg.to_string())
403 }
404}
405
406fn value_to_unexpected(value: &Value) -> Unexpected {
407 match value.0 {
408 ValueRepr::Undefined(_) | ValueRepr::None => Unexpected::Unit,
409 ValueRepr::Bool(val) => Unexpected::Bool(val),
410 ValueRepr::U64(val) => Unexpected::Unsigned(val),
411 ValueRepr::I64(val) => Unexpected::Signed(val),
412 ValueRepr::F64(val) => Unexpected::Float(val),
413 ValueRepr::Invalid(_) => Unexpected::Other("<invalid value>"),
414 ValueRepr::U128(val) => {
415 let unsigned = val.0 as u64;
416 if unsigned as u128 == val.0 {
417 Unexpected::Unsigned(unsigned)
418 } else {
419 Unexpected::Other("u128")
420 }
421 }
422 ValueRepr::I128(val) => {
423 let signed = val.0 as i64;
424 if signed as i128 == val.0 {
425 Unexpected::Signed(signed)
426 } else {
427 Unexpected::Other("u128")
428 }
429 }
430 ValueRepr::String(ref s, _) => Unexpected::Str(s),
431 ValueRepr::SmallStr(ref s) => Unexpected::Str(s.as_str()),
432 ValueRepr::Bytes(ref b) => Unexpected::Bytes(b),
433 ValueRepr::Object(..) => Unexpected::Other("<dynamic value>"),
434 }
435}