keyvalues_serde/
ser.rs

1//! Serialize Rust types to VDF text
2
3use keyvalues_parser::Vdf;
4use serde_core::{ser, Serialize};
5
6use std::io::Write;
7
8use crate::{
9    error::{Error, Result},
10    tokens::{NaiveToken, NaiveTokenStream},
11};
12
13/// The struct for serializing Rust values into VDF text
14///
15/// This typically doesn't need to be invoked directly when [`to_writer()`] and
16/// [`to_writer_with_key()`] can be used instead
17#[derive(Default)]
18pub struct Serializer {
19    tokens: NaiveTokenStream,
20}
21
22impl Serializer {
23    /// Creates a new VDF serializer
24    pub fn new() -> Self {
25        Self::default()
26    }
27}
28
29/// Serialize the `value` into an IO stream of VDF text
30///
31/// # Errors
32///
33/// This will return an error if the input can't be represented with valid VDF
34pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
35where
36    W: Write,
37    T: Serialize,
38{
39    _to_writer(writer, value, None)
40}
41
42/// Serialize the `value` into an IO stream of VDF text with a custom top level VDF key
43///
44/// # Errors
45///
46/// This will return an error if the input can't be represented with valid VDF
47pub fn to_writer_with_key<W, T>(writer: &mut W, value: &T, key: &str) -> Result<()>
48where
49    W: Write,
50    T: Serialize,
51{
52    _to_writer(writer, value, Some(key))
53}
54
55// Serialization process goes as follows:
56// value: &T
57// -> NaiveTokenStream
58// -> Vdf (fails on invalid VDF structure like nested sequences)
59// -> Formatted
60// Which is a bit of a long-winded process just to serialize some text, but it comes with
61// validation (NaiveTokenStream -> Vdf) and reuses portions from the parser (Vdf -> Formatted)
62fn _to_writer<W, T>(writer: &mut W, value: &T, maybe_key: Option<&str>) -> Result<()>
63where
64    W: Write,
65    T: Serialize,
66{
67    let mut serializer = Serializer::new();
68    value.serialize(&mut serializer)?;
69
70    if let Some(key) = maybe_key {
71        match serializer.tokens.first() {
72            // Replace the old key
73            Some(NaiveToken::Str(_old_key)) => {
74                serializer.tokens[0] = NaiveToken::Str(key.to_owned());
75            }
76            // Push on the key
77            Some(_) => serializer.tokens.insert(0, NaiveToken::Str(key.to_owned())),
78            None => {}
79        }
80    }
81
82    let vdf = Vdf::try_from(&serializer.tokens)?;
83    write!(writer, "{vdf}")?;
84
85    Ok(())
86}
87
88/// Attempts to serialize some input to VDF text
89///
90/// # Errors
91///
92/// This will return an error if the input can't be represented with valid VDF
93pub fn to_string<T>(value: &T) -> Result<String>
94where
95    T: Serialize,
96{
97    let mut buffer = Vec::new();
98    to_writer(&mut buffer, value)?;
99    let s = String::from_utf8(buffer).expect("Input was all valid UTF-8");
100
101    Ok(s)
102}
103
104/// Attempts to serialize some input to VDF text with a custom top level VDF key
105///
106/// # Errors
107///
108/// This will return an error if the input can't be represented with valid VDF
109pub fn to_string_with_key<T>(value: &T, key: &str) -> Result<String>
110where
111    T: Serialize,
112{
113    let mut buffer = Vec::new();
114    to_writer_with_key(&mut buffer, value, key)?;
115    let s = String::from_utf8(buffer).expect("Input was all valid UTF-8");
116
117    Ok(s)
118}
119
120macro_rules! forward_serialize_as_str {
121    ( $( ( $method:ident, $ty:ty ) ),* $(,)? ) => {
122        $(
123            fn $method(self, v: $ty) -> Result<()> {
124                self.serialize_str(&v.to_string())
125            }
126        )*
127    }
128}
129
130impl ser::Serializer for &mut Serializer {
131    type Ok = ();
132
133    type Error = Error;
134
135    type SerializeSeq = Self;
136    type SerializeTuple = Self;
137    type SerializeTupleStruct = Self;
138    type SerializeTupleVariant = Self;
139    type SerializeMap = Self;
140    type SerializeStruct = Self;
141    type SerializeStructVariant = Self;
142
143    forward_serialize_as_str!(
144        (serialize_i8, i8),
145        (serialize_i16, i16),
146        (serialize_i32, i32),
147        (serialize_i64, i64),
148        (serialize_i128, i128),
149        (serialize_u8, u8),
150        (serialize_u16, u16),
151        (serialize_u32, u32),
152        (serialize_u64, u64),
153        (serialize_u128, u128),
154        (serialize_char, char),
155    );
156
157    fn serialize_str(self, v: &str) -> Result<()> {
158        self.tokens.push(NaiveToken::str(v));
159        Ok(())
160    }
161
162    fn serialize_bool(self, v: bool) -> Result<()> {
163        self.serialize_i8(v as i8)
164    }
165
166    fn serialize_f32(self, v: f32) -> Result<()> {
167        if v.is_finite() {
168            self.serialize_str(&v.to_string())
169        } else {
170            Err(Error::NonFiniteFloat(v))
171        }
172    }
173
174    fn serialize_f64(self, v: f64) -> Result<()> {
175        // TODO: include this and empty vecs and nested Option<Vec> in potential pitfalls
176        // TODO: look into this more, might be the other way around if the wiki is wrong
177        // Note: I believe floats in VDF are considered f32 so even when you use an f64 it will get
178        // converted to an f32 when serialized
179        self.serialize_f32(v as f32)
180    }
181
182    fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
183        Err(Error::Unsupported("Bytes"))
184    }
185
186    fn serialize_none(self) -> Result<()> {
187        self.tokens.push(NaiveToken::Null);
188        Ok(())
189    }
190
191    fn serialize_some<T>(self, value: &T) -> Result<()>
192    where
193        T: ?Sized + Serialize,
194    {
195        // Just serializes the contained value
196        value.serialize(self)
197    }
198
199    fn serialize_unit(self) -> Result<()> {
200        Err(Error::Unsupported("Unit Type"))
201    }
202
203    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
204        Err(Error::Unsupported("Unit Struct"))
205    }
206
207    fn serialize_unit_variant(
208        self,
209        _name: &'static str,
210        _variant_index: u32,
211        variant: &'static str,
212    ) -> Result<()> {
213        // Just pass the variant name for unit variant enums
214        self.serialize_str(variant)
215    }
216
217    fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
218    where
219        T: ?Sized + Serialize,
220    {
221        // Just a wrapper over the contained value
222        value.serialize(self)
223    }
224
225    fn serialize_newtype_variant<T>(
226        self,
227        _name: &'static str,
228        _variant_index: u32,
229        _variant: &'static str,
230        _value: &T,
231    ) -> Result<()>
232    where
233        T: ?Sized + Serialize,
234    {
235        Err(Error::Unsupported("Enum Newtype Variant"))
236    }
237
238    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
239        self.tokens.push(NaiveToken::SeqBegin);
240        Ok(self)
241    }
242
243    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
244        self.serialize_seq(Some(len))
245    }
246
247    fn serialize_tuple_struct(
248        self,
249        _name: &'static str,
250        len: usize,
251    ) -> Result<Self::SerializeTupleStruct> {
252        self.serialize_tuple(len)
253    }
254
255    fn serialize_tuple_variant(
256        self,
257        _name: &'static str,
258        _variant_index: u32,
259        _variant: &'static str,
260        _len: usize,
261    ) -> Result<Self::SerializeTupleVariant> {
262        Ok(self)
263    }
264
265    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
266        self.tokens.push(NaiveToken::ObjBegin);
267        Ok(self)
268    }
269
270    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
271        // The top level key is the name of the struct
272        if self.tokens.is_empty() {
273            self.serialize_str(name)?;
274        }
275
276        self.serialize_map(Some(len))
277    }
278
279    fn serialize_struct_variant(
280        self,
281        _name: &'static str,
282        _variant_index: u32,
283        _variant: &'static str,
284        _len: usize,
285    ) -> Result<Self::SerializeStructVariant> {
286        Ok(self)
287    }
288}
289
290impl ser::SerializeSeq for &mut Serializer {
291    type Ok = ();
292    type Error = Error;
293
294    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
295    where
296        T: ?Sized + Serialize,
297    {
298        value.serialize(&mut **self)
299    }
300
301    fn end(self) -> Result<()> {
302        self.tokens.push(NaiveToken::SeqEnd);
303        Ok(())
304    }
305}
306
307impl ser::SerializeTuple for &mut Serializer {
308    type Ok = ();
309    type Error = Error;
310
311    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
312    where
313        T: ?Sized + Serialize,
314    {
315        value.serialize(&mut **self)
316    }
317
318    fn end(self) -> Result<()> {
319        self.tokens.push(NaiveToken::SeqEnd);
320        Ok(())
321    }
322}
323
324impl ser::SerializeTupleStruct for &mut Serializer {
325    type Ok = ();
326    type Error = Error;
327
328    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
329    where
330        T: ?Sized + Serialize,
331    {
332        value.serialize(&mut **self)
333    }
334
335    fn end(self) -> Result<()> {
336        self.tokens.push(NaiveToken::SeqEnd);
337        Ok(())
338    }
339}
340
341impl ser::SerializeTupleVariant for &mut Serializer {
342    type Ok = ();
343    type Error = Error;
344
345    fn serialize_field<T>(&mut self, _value: &T) -> Result<()>
346    where
347        T: ?Sized + Serialize,
348    {
349        Err(Error::Unsupported("Enum Tuple Variant"))
350    }
351
352    fn end(self) -> Result<()> {
353        Err(Error::Unsupported("Enum Tuple Variant"))
354    }
355}
356
357impl ser::SerializeMap for &mut Serializer {
358    type Ok = ();
359    type Error = Error;
360
361    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
362    where
363        T: ?Sized + Serialize,
364    {
365        key.serialize(&mut **self)
366    }
367
368    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
369    where
370        T: ?Sized + Serialize,
371    {
372        value.serialize(&mut **self)
373    }
374
375    fn end(self) -> Result<()> {
376        self.tokens.push(NaiveToken::ObjEnd);
377        Ok(())
378    }
379}
380
381impl ser::SerializeStruct for &mut Serializer {
382    type Ok = ();
383    type Error = Error;
384
385    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
386    where
387        T: ?Sized + Serialize,
388    {
389        key.serialize(&mut **self)?;
390        value.serialize(&mut **self)
391    }
392
393    fn end(self) -> Result<()> {
394        self.tokens.push(NaiveToken::ObjEnd);
395        Ok(())
396    }
397}
398
399impl ser::SerializeStructVariant for &mut Serializer {
400    type Ok = ();
401    type Error = Error;
402
403    fn serialize_field<T>(&mut self, _key: &'static str, _value: &T) -> Result<()>
404    where
405        T: ?Sized + Serialize,
406    {
407        Err(Error::Unsupported("Enum Struct Variant"))
408    }
409
410    fn end(self) -> Result<()> {
411        Err(Error::Unsupported("Enum Struct Variant"))
412    }
413}