minijinja/value/
serialize.rs

1use std::collections::BTreeMap;
2use std::fmt;
3
4use serde::{ser, Serialize, Serializer};
5
6use crate::error::{Error, ErrorKind};
7use crate::utils::untrusted_size_hint;
8use crate::value::{
9    value_map_with_capacity, Arc, Packed, Value, ValueMap, ValueRepr, VALUE_HANDLES,
10    VALUE_HANDLE_MARKER,
11};
12
13#[derive(Debug)]
14pub struct InvalidValue(String);
15
16impl std::error::Error for InvalidValue {}
17
18impl fmt::Display for InvalidValue {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        self.0.fmt(f)
21    }
22}
23
24impl serde::ser::Error for InvalidValue {
25    fn custom<T>(msg: T) -> Self
26    where
27        T: fmt::Display,
28    {
29        InvalidValue(msg.to_string())
30    }
31}
32
33/// Transforms a serializable value to a value object.
34///
35/// This neither fails nor panics.  For objects that cannot be represented
36/// the value might be represented as a half broken error object.
37pub fn transform<T: Serialize>(value: T) -> Value {
38    match value.serialize(ValueSerializer) {
39        Ok(rv) => rv,
40        Err(invalid) => Value::from(Error::new(ErrorKind::BadSerialization, invalid.0)),
41    }
42}
43
44pub struct ValueSerializer;
45
46impl Serializer for ValueSerializer {
47    type Ok = Value;
48    type Error = InvalidValue;
49
50    type SerializeSeq = SerializeSeq;
51    type SerializeTuple = SerializeTuple;
52    type SerializeTupleStruct = SerializeTupleStruct;
53    type SerializeTupleVariant = SerializeTupleVariant;
54    type SerializeMap = SerializeMap;
55    type SerializeStruct = SerializeStruct;
56    type SerializeStructVariant = SerializeStructVariant;
57
58    fn serialize_bool(self, v: bool) -> Result<Value, InvalidValue> {
59        Ok(ValueRepr::Bool(v).into())
60    }
61
62    fn serialize_i8(self, v: i8) -> Result<Value, InvalidValue> {
63        Ok(ValueRepr::I64(v as i64).into())
64    }
65
66    fn serialize_i16(self, v: i16) -> Result<Value, InvalidValue> {
67        Ok(ValueRepr::I64(v as i64).into())
68    }
69
70    fn serialize_i32(self, v: i32) -> Result<Value, InvalidValue> {
71        Ok(ValueRepr::I64(v as i64).into())
72    }
73
74    fn serialize_i64(self, v: i64) -> Result<Value, InvalidValue> {
75        Ok(ValueRepr::I64(v).into())
76    }
77
78    fn serialize_i128(self, v: i128) -> Result<Value, InvalidValue> {
79        Ok(ValueRepr::I128(Packed(v)).into())
80    }
81
82    fn serialize_u8(self, v: u8) -> Result<Value, InvalidValue> {
83        Ok(ValueRepr::U64(v as u64).into())
84    }
85
86    fn serialize_u16(self, v: u16) -> Result<Value, InvalidValue> {
87        Ok(ValueRepr::U64(v as u64).into())
88    }
89
90    fn serialize_u32(self, v: u32) -> Result<Value, InvalidValue> {
91        Ok(ValueRepr::U64(v as u64).into())
92    }
93
94    fn serialize_u64(self, v: u64) -> Result<Value, InvalidValue> {
95        Ok(ValueRepr::U64(v).into())
96    }
97
98    fn serialize_u128(self, v: u128) -> Result<Value, InvalidValue> {
99        Ok(ValueRepr::U128(Packed(v)).into())
100    }
101
102    fn serialize_f32(self, v: f32) -> Result<Value, InvalidValue> {
103        Ok(ValueRepr::F64(v as f64).into())
104    }
105
106    fn serialize_f64(self, v: f64) -> Result<Value, InvalidValue> {
107        Ok(ValueRepr::F64(v).into())
108    }
109
110    fn serialize_char(self, v: char) -> Result<Value, InvalidValue> {
111        Ok(Value::from(v))
112    }
113
114    fn serialize_str(self, value: &str) -> Result<Value, InvalidValue> {
115        Ok(Value::from(value))
116    }
117
118    fn serialize_bytes(self, value: &[u8]) -> Result<Value, InvalidValue> {
119        Ok(ValueRepr::Bytes(Arc::new(value.to_owned())).into())
120    }
121
122    fn serialize_none(self) -> Result<Value, InvalidValue> {
123        Ok(ValueRepr::None.into())
124    }
125
126    fn serialize_some<T>(self, value: &T) -> Result<Value, InvalidValue>
127    where
128        T: Serialize + ?Sized,
129    {
130        Ok(transform(value))
131    }
132
133    fn serialize_unit(self) -> Result<Value, InvalidValue> {
134        Ok(ValueRepr::None.into())
135    }
136
137    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, InvalidValue> {
138        Ok(ValueRepr::None.into())
139    }
140
141    fn serialize_unit_variant(
142        self,
143        _name: &'static str,
144        _variant_index: u32,
145        variant: &'static str,
146    ) -> Result<Value, InvalidValue> {
147        Ok(Value::from(variant))
148    }
149
150    fn serialize_newtype_struct<T>(
151        self,
152        _name: &'static str,
153        value: &T,
154    ) -> Result<Value, InvalidValue>
155    where
156        T: Serialize + ?Sized,
157    {
158        Ok(transform(value))
159    }
160
161    fn serialize_newtype_variant<T>(
162        self,
163        _name: &'static str,
164        _variant_index: u32,
165        variant: &'static str,
166        value: &T,
167    ) -> Result<Value, InvalidValue>
168    where
169        T: Serialize + ?Sized,
170    {
171        let mut map = value_map_with_capacity(1);
172        map.insert(variant.into(), transform(value));
173        Ok(Value::from_object(map))
174    }
175
176    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, InvalidValue> {
177        Ok(SerializeSeq {
178            elements: Vec::with_capacity(untrusted_size_hint(len.unwrap_or(0))),
179        })
180    }
181
182    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, InvalidValue> {
183        Ok(SerializeTuple {
184            elements: Vec::with_capacity(untrusted_size_hint(len)),
185        })
186    }
187
188    fn serialize_tuple_struct(
189        self,
190        name: &'static str,
191        len: usize,
192    ) -> Result<Self::SerializeTupleStruct, InvalidValue> {
193        Ok(if name == VALUE_HANDLE_MARKER {
194            SerializeTupleStruct::Handle(None)
195        } else {
196            SerializeTupleStruct::Fields(Vec::with_capacity(untrusted_size_hint(len)))
197        })
198    }
199
200    fn serialize_tuple_variant(
201        self,
202        _name: &'static str,
203        _variant_index: u32,
204        variant: &'static str,
205        len: usize,
206    ) -> Result<Self::SerializeTupleVariant, InvalidValue> {
207        Ok(SerializeTupleVariant {
208            name: variant,
209            fields: Vec::with_capacity(untrusted_size_hint(len)),
210        })
211    }
212
213    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, InvalidValue> {
214        Ok(SerializeMap {
215            entries: value_map_with_capacity(len.unwrap_or(0)),
216            key: None,
217        })
218    }
219
220    fn serialize_struct(
221        self,
222        _name: &'static str,
223        len: usize,
224    ) -> Result<Self::SerializeStruct, InvalidValue> {
225        Ok(SerializeStruct {
226            fields: value_map_with_capacity(len),
227        })
228    }
229
230    fn serialize_struct_variant(
231        self,
232        _name: &'static str,
233        _variant_index: u32,
234        variant: &'static str,
235        len: usize,
236    ) -> Result<Self::SerializeStructVariant, InvalidValue> {
237        Ok(SerializeStructVariant {
238            variant,
239            map: value_map_with_capacity(len),
240        })
241    }
242}
243
244pub struct SerializeSeq {
245    elements: Vec<Value>,
246}
247
248impl ser::SerializeSeq for SerializeSeq {
249    type Ok = Value;
250    type Error = InvalidValue;
251
252    fn serialize_element<T>(&mut self, value: &T) -> Result<(), InvalidValue>
253    where
254        T: Serialize + ?Sized,
255    {
256        self.elements.push(transform(value));
257        Ok(())
258    }
259
260    fn end(self) -> Result<Value, InvalidValue> {
261        Ok(Value::from_object(self.elements))
262    }
263}
264
265pub struct SerializeTuple {
266    elements: Vec<Value>,
267}
268
269impl ser::SerializeTuple for SerializeTuple {
270    type Ok = Value;
271    type Error = InvalidValue;
272
273    fn serialize_element<T>(&mut self, value: &T) -> Result<(), InvalidValue>
274    where
275        T: Serialize + ?Sized,
276    {
277        self.elements.push(transform(value));
278        Ok(())
279    }
280
281    fn end(self) -> Result<Value, InvalidValue> {
282        Ok(Value::from_object(self.elements))
283    }
284}
285
286pub enum SerializeTupleStruct {
287    Handle(Option<u32>),
288    Fields(Vec<Value>),
289}
290
291impl ser::SerializeTupleStruct for SerializeTupleStruct {
292    type Ok = Value;
293    type Error = InvalidValue;
294
295    fn serialize_field<T>(&mut self, value: &T) -> Result<(), InvalidValue>
296    where
297        T: Serialize + ?Sized,
298    {
299        match self {
300            SerializeTupleStruct::Handle(ref mut handle) => {
301                *handle = transform(value).as_usize().map(|x| x as u32);
302            }
303            SerializeTupleStruct::Fields(ref mut fields) => {
304                fields.push(transform(value));
305            }
306        }
307        Ok(())
308    }
309
310    fn end(self) -> Result<Value, InvalidValue> {
311        match self {
312            SerializeTupleStruct::Handle(handle) => VALUE_HANDLES.with(|handles| {
313                handle
314                    .and_then(|h| handles.borrow_mut().remove(&h))
315                    .ok_or_else(|| InvalidValue("value handle not in registry".into()))
316            }),
317            SerializeTupleStruct::Fields(fields) => Ok(Value::from_object(fields)),
318        }
319    }
320}
321
322pub struct SerializeTupleVariant {
323    name: &'static str,
324    fields: Vec<Value>,
325}
326
327impl ser::SerializeTupleVariant for SerializeTupleVariant {
328    type Ok = Value;
329    type Error = InvalidValue;
330
331    fn serialize_field<T>(&mut self, value: &T) -> Result<(), InvalidValue>
332    where
333        T: Serialize + ?Sized,
334    {
335        self.fields.push(transform(value));
336        Ok(())
337    }
338
339    fn end(self) -> Result<Value, InvalidValue> {
340        let mut map = value_map_with_capacity(1);
341        map.insert(self.name.into(), Value::from_object(self.fields));
342        Ok(Value::from_object(map))
343    }
344}
345
346pub struct SerializeMap {
347    entries: ValueMap,
348    key: Option<Value>,
349}
350
351impl ser::SerializeMap for SerializeMap {
352    type Ok = Value;
353    type Error = InvalidValue;
354
355    fn serialize_key<T>(&mut self, key: &T) -> Result<(), InvalidValue>
356    where
357        T: Serialize + ?Sized,
358    {
359        match key.serialize(ValueSerializer) {
360            Ok(key) => self.key = Some(key),
361            Err(_) => self.key = None,
362        }
363        Ok(())
364    }
365
366    fn serialize_value<T>(&mut self, value: &T) -> Result<(), InvalidValue>
367    where
368        T: Serialize + ?Sized,
369    {
370        if let Some(key) = self.key.take() {
371            self.entries.insert(key, transform(value));
372        }
373        Ok(())
374    }
375
376    fn end(self) -> Result<Value, InvalidValue> {
377        Ok(Value::from_object(self.entries))
378    }
379
380    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), InvalidValue>
381    where
382        K: Serialize + ?Sized,
383        V: Serialize + ?Sized,
384    {
385        if let Ok(key) = key.serialize(ValueSerializer) {
386            self.entries.insert(key, transform(value));
387        }
388        Ok(())
389    }
390}
391
392pub struct SerializeStruct {
393    fields: ValueMap,
394}
395
396impl ser::SerializeStruct for SerializeStruct {
397    type Ok = Value;
398    type Error = InvalidValue;
399
400    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), InvalidValue>
401    where
402        T: Serialize + ?Sized,
403    {
404        self.fields.insert(key.into(), transform(value));
405        Ok(())
406    }
407
408    fn end(self) -> Result<Value, InvalidValue> {
409        Ok(Value::from_object(self.fields))
410    }
411}
412
413pub struct SerializeStructVariant {
414    variant: &'static str,
415    map: ValueMap,
416}
417
418impl ser::SerializeStructVariant for SerializeStructVariant {
419    type Ok = Value;
420    type Error = InvalidValue;
421
422    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), InvalidValue>
423    where
424        T: Serialize + ?Sized,
425    {
426        self.map.insert(key.into(), transform(value));
427        Ok(())
428    }
429
430    fn end(self) -> Result<Value, InvalidValue> {
431        let mut rv = BTreeMap::new();
432        rv.insert(self.variant.to_string(), Value::from_object(self.map));
433        Ok(rv.into())
434    }
435}