Skip to main content

snix_serde/
ser.rs

1//! Serialisation from Rust values to Nix.
2
3use serde::ser;
4use snix_eval::{NixAttrs, NixList, NixString, Value};
5
6use crate::error::Error;
7
8/// Serialise a Rust value into a [`snix_eval::Value`].
9///
10/// This is the inverse of [`crate::from_value`].
11pub fn to_value<T: serde::Serialize>(value: &T) -> Result<Value, Error> {
12    value.serialize(NixSerializer)
13}
14
15/// Serialise a Rust value into a Nix code string.
16///
17/// This is a convenience wrapper around [`to_value`] which converts the resulting
18/// [`snix_eval::Value`] into a string.
19pub fn to_string<T: serde::Serialize>(value: &T) -> Result<String, Error> {
20    let v = to_value(value)?;
21    Ok(v.to_string())
22}
23
24struct NixSerializer;
25
26impl ser::Serializer for NixSerializer {
27    type Ok = Value;
28    type Error = Error;
29
30    type SerializeSeq = SeqSerializer;
31    type SerializeTuple = SeqSerializer;
32    type SerializeTupleStruct = SeqSerializer;
33    type SerializeTupleVariant = TupleVariantSerializer;
34    type SerializeMap = MapSerializer;
35    type SerializeStruct = MapSerializer;
36    type SerializeStructVariant = StructVariantSerializer;
37
38    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
39        Ok(Value::Bool(v))
40    }
41
42    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
43        Ok(Value::Integer(v as i64))
44    }
45
46    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
47        Ok(Value::Integer(v as i64))
48    }
49
50    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
51        Ok(Value::Integer(v as i64))
52    }
53
54    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
55        Ok(Value::Integer(v))
56    }
57
58    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
59        Ok(Value::Integer(v as i64))
60    }
61
62    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
63        Ok(Value::Integer(v as i64))
64    }
65
66    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
67        Ok(Value::Integer(v as i64))
68    }
69
70    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
71        i64::try_from(v)
72            .map(Value::Integer)
73            .map_err(|_| Error::IntegerOverflow { got: v })
74    }
75
76    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
77        Ok(Value::Float(v as f64))
78    }
79
80    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
81        Ok(Value::Float(v))
82    }
83
84    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
85        let mut buf = [0u8; 4];
86        Ok(Value::String(NixString::from(
87            v.encode_utf8(&mut buf) as &str
88        )))
89    }
90
91    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
92        Ok(Value::String(NixString::from(v)))
93    }
94
95    fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
96        Err(Error::Unsupported { wanted: "bytes" })
97    }
98
99    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
100        Ok(Value::Null)
101    }
102
103    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
104    where
105        T: ?Sized + serde::Serialize,
106    {
107        value.serialize(self)
108    }
109
110    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
111        Ok(Value::Null)
112    }
113
114    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
115        Ok(Value::Null)
116    }
117
118    // Unit variants are serialised as plain strings, mirroring
119    // `deserialize_enum` in de.rs which maps a Nix string to a unit variant.
120    fn serialize_unit_variant(
121        self,
122        _name: &'static str,
123        _variant_index: u32,
124        variant: &'static str,
125    ) -> Result<Self::Ok, Self::Error> {
126        Ok(Value::String(NixString::from(variant)))
127    }
128
129    fn serialize_newtype_struct<T>(
130        self,
131        _name: &'static str,
132        value: &T,
133    ) -> Result<Self::Ok, Self::Error>
134    where
135        T: ?Sized + serde::Serialize,
136    {
137        value.serialize(self)
138    }
139
140    // Newtype variants are serialised as `{ VariantName = value; }`.
141    fn serialize_newtype_variant<T>(
142        self,
143        _name: &'static str,
144        _variant_index: u32,
145        variant: &'static str,
146        value: &T,
147    ) -> Result<Self::Ok, Self::Error>
148    where
149        T: ?Sized + serde::Serialize,
150    {
151        let inner = value.serialize(NixSerializer)?;
152        Ok(Value::Attrs(NixAttrs::from_iter([(variant, inner)])))
153    }
154
155    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
156        Ok(SeqSerializer {
157            items: Vec::with_capacity(len.unwrap_or(0)),
158        })
159    }
160
161    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
162        self.serialize_seq(Some(len))
163    }
164
165    fn serialize_tuple_struct(
166        self,
167        _name: &'static str,
168        len: usize,
169    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
170        self.serialize_seq(Some(len))
171    }
172
173    // Tuple variants are serialised as `{ VariantName = [a b ...]; }`.
174    fn serialize_tuple_variant(
175        self,
176        _name: &'static str,
177        _variant_index: u32,
178        variant: &'static str,
179        len: usize,
180    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
181        Ok(TupleVariantSerializer {
182            variant,
183            seq: SeqSerializer {
184                items: Vec::with_capacity(len),
185            },
186        })
187    }
188
189    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
190        Ok(MapSerializer {
191            entries: Vec::with_capacity(len.unwrap_or(0)),
192            pending_key: None,
193        })
194    }
195
196    fn serialize_struct(
197        self,
198        _name: &'static str,
199        len: usize,
200    ) -> Result<Self::SerializeStruct, Self::Error> {
201        self.serialize_map(Some(len))
202    }
203
204    // Struct variants are serialised as `{ VariantName = { fields... }; }`.
205    fn serialize_struct_variant(
206        self,
207        _name: &'static str,
208        _variant_index: u32,
209        variant: &'static str,
210        len: usize,
211    ) -> Result<Self::SerializeStructVariant, Self::Error> {
212        Ok(StructVariantSerializer {
213            variant,
214            map: MapSerializer {
215                entries: Vec::with_capacity(len),
216                pending_key: None,
217            },
218        })
219    }
220}
221
222struct SeqSerializer {
223    items: Vec<Value>,
224}
225
226impl ser::SerializeSeq for SeqSerializer {
227    type Ok = Value;
228    type Error = Error;
229
230    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
231    where
232        T: ?Sized + serde::Serialize,
233    {
234        self.items.push(value.serialize(NixSerializer)?);
235        Ok(())
236    }
237
238    fn end(self) -> Result<Self::Ok, Self::Error> {
239        Ok(Value::List(NixList::from(self.items)))
240    }
241}
242
243impl ser::SerializeTuple for SeqSerializer {
244    type Ok = Value;
245    type Error = Error;
246
247    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
248    where
249        T: ?Sized + serde::Serialize,
250    {
251        self.items.push(value.serialize(NixSerializer)?);
252        Ok(())
253    }
254
255    fn end(self) -> Result<Self::Ok, Self::Error> {
256        Ok(Value::List(NixList::from(self.items)))
257    }
258}
259
260impl ser::SerializeTupleStruct for SeqSerializer {
261    type Ok = Value;
262    type Error = Error;
263
264    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
265    where
266        T: ?Sized + serde::Serialize,
267    {
268        self.items.push(value.serialize(NixSerializer)?);
269        Ok(())
270    }
271
272    fn end(self) -> Result<Self::Ok, Self::Error> {
273        Ok(Value::List(NixList::from(self.items)))
274    }
275}
276
277struct TupleVariantSerializer {
278    variant: &'static str,
279    seq: SeqSerializer,
280}
281
282impl ser::SerializeTupleVariant for TupleVariantSerializer {
283    type Ok = Value;
284    type Error = Error;
285
286    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
287    where
288        T: ?Sized + serde::Serialize,
289    {
290        self.seq.items.push(value.serialize(NixSerializer)?);
291        Ok(())
292    }
293
294    fn end(self) -> Result<Self::Ok, Self::Error> {
295        let list = Value::List(NixList::from(self.seq.items));
296        Ok(Value::Attrs(NixAttrs::from_iter([(self.variant, list)])))
297    }
298}
299
300struct MapSerializer {
301    entries: Vec<(NixString, Value)>,
302    pending_key: Option<NixString>,
303}
304
305/// Extract the NixString from a serialized key value; only string keys are
306/// valid in Nix attribute sets.
307fn value_to_nixstring(v: Value) -> Result<NixString, Error> {
308    match v {
309        Value::String(s) => Ok(s),
310        _ => Err(Error::NonStringKey),
311    }
312}
313
314impl ser::SerializeMap for MapSerializer {
315    type Ok = Value;
316    type Error = Error;
317
318    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
319    where
320        T: ?Sized + serde::Serialize,
321    {
322        let v = key.serialize(NixSerializer)?;
323        self.pending_key = Some(value_to_nixstring(v)?);
324        Ok(())
325    }
326
327    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
328    where
329        T: ?Sized + serde::Serialize,
330    {
331        let key = self
332            .pending_key
333            .take()
334            .expect("serialize_value called before serialize_key");
335        let val = value.serialize(NixSerializer)?;
336        self.entries.push((key, val));
337        Ok(())
338    }
339
340    fn end(self) -> Result<Self::Ok, Self::Error> {
341        Ok(Value::Attrs(NixAttrs::from_iter(self.entries)))
342    }
343}
344
345impl ser::SerializeStruct for MapSerializer {
346    type Ok = Value;
347    type Error = Error;
348
349    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
350    where
351        T: ?Sized + serde::Serialize,
352    {
353        let val = value.serialize(NixSerializer)?;
354        self.entries.push((NixString::from(key), val));
355        Ok(())
356    }
357
358    fn end(self) -> Result<Self::Ok, Self::Error> {
359        ser::SerializeMap::end(self)
360    }
361}
362
363struct StructVariantSerializer {
364    variant: &'static str,
365    map: MapSerializer,
366}
367
368impl ser::SerializeStructVariant for StructVariantSerializer {
369    type Ok = Value;
370    type Error = Error;
371
372    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
373    where
374        T: ?Sized + serde::Serialize,
375    {
376        ser::SerializeStruct::serialize_field(&mut self.map, key, value)
377    }
378
379    fn end(self) -> Result<Self::Ok, Self::Error> {
380        let inner = ser::SerializeStruct::end(self.map)?;
381        Ok(Value::Attrs(NixAttrs::from_iter([(self.variant, inner)])))
382    }
383}