piccolo_util/serde/
ser.rs

1use std::fmt;
2
3use piccolo::{Context, Table, Value};
4use serde::ser;
5use thiserror::Error;
6
7use super::markers::{none, unit};
8
9#[derive(Debug, Error)]
10#[error("{0}")]
11pub struct Error(String);
12
13impl ser::Error for Error {
14    fn custom<T: fmt::Display>(msg: T) -> Self {
15        Error(msg.to_string())
16    }
17}
18
19#[derive(Debug, Copy, Clone)]
20#[non_exhaustive]
21pub struct Options {
22    /// If true, serialize the special `none` marker instead of `nil`.
23    pub serialize_none: bool,
24}
25
26impl Default for Options {
27    fn default() -> Self {
28        Self {
29            serialize_none: false,
30        }
31    }
32}
33
34impl Options {
35    pub fn serialize_none(mut self, enabled: bool) -> Self {
36        self.serialize_none = enabled;
37        self
38    }
39}
40
41pub fn to_value<'gc, T: ser::Serialize>(ctx: Context<'gc>, value: &T) -> Result<Value<'gc>, Error> {
42    value.serialize(Serializer::new(ctx, Options::default()))
43}
44
45pub fn to_value_with<'gc, T: ser::Serialize>(
46    ctx: Context<'gc>,
47    value: &T,
48    options: Options,
49) -> Result<Value<'gc>, Error> {
50    value.serialize(Serializer::new(ctx, options))
51}
52
53#[derive(Copy, Clone)]
54pub struct Serializer<'gc> {
55    ctx: Context<'gc>,
56    options: Options,
57}
58
59impl<'gc> Serializer<'gc> {
60    pub fn new(ctx: Context<'gc>, options: Options) -> Self {
61        Self { ctx, options }
62    }
63}
64
65impl<'gc> ser::Serializer for Serializer<'gc> {
66    type Ok = Value<'gc>;
67    type Error = Error;
68
69    type SerializeSeq = SerializeSeq<'gc>;
70    type SerializeTuple = SerializeSeq<'gc>;
71    type SerializeTupleStruct = SerializeSeq<'gc>;
72    type SerializeTupleVariant = SerializeTupleVariant<'gc>;
73    type SerializeMap = SerializeMap<'gc>;
74    type SerializeStruct = SerializeStruct<'gc>;
75    type SerializeStructVariant = SerializeStructVariant<'gc>;
76
77    fn serialize_bool(self, v: bool) -> Result<Value<'gc>, Error> {
78        Ok(Value::Boolean(v))
79    }
80
81    fn serialize_i8(self, v: i8) -> Result<Value<'gc>, Error> {
82        self.serialize_i64(v.into())
83    }
84
85    fn serialize_i16(self, v: i16) -> Result<Value<'gc>, Error> {
86        self.serialize_i64(v.into())
87    }
88
89    fn serialize_i32(self, v: i32) -> Result<Value<'gc>, Error> {
90        self.serialize_i64(v.into())
91    }
92
93    fn serialize_i64(self, v: i64) -> Result<Value<'gc>, Error> {
94        Ok(Value::Integer(v))
95    }
96
97    fn serialize_u8(self, v: u8) -> Result<Value<'gc>, Error> {
98        self.serialize_u64(v.into())
99    }
100
101    fn serialize_u16(self, v: u16) -> Result<Value<'gc>, Error> {
102        self.serialize_u64(v.into())
103    }
104
105    fn serialize_u32(self, v: u32) -> Result<Value<'gc>, Error> {
106        self.serialize_u64(v.into())
107    }
108
109    fn serialize_u64(self, v: u64) -> Result<Value<'gc>, Error> {
110        if let Ok(i) = i64::try_from(v) {
111            Ok(Value::Integer(i))
112        } else {
113            self.serialize_f64(v as f64)
114        }
115    }
116
117    fn serialize_f32(self, v: f32) -> Result<Value<'gc>, Error> {
118        self.serialize_f64(v.into())
119    }
120
121    fn serialize_f64(self, v: f64) -> Result<Value<'gc>, Error> {
122        Ok(Value::Number(v))
123    }
124
125    fn serialize_char(self, v: char) -> Result<Value<'gc>, Error> {
126        self.serialize_str(&v.to_string())
127    }
128
129    fn serialize_str(self, v: &str) -> Result<Value<'gc>, Error> {
130        self.serialize_bytes(v.as_bytes())
131    }
132
133    fn serialize_bytes(self, v: &[u8]) -> Result<Value<'gc>, Error> {
134        Ok(self.ctx.intern(v).into())
135    }
136
137    fn serialize_none(self) -> Result<Value<'gc>, Error> {
138        Ok(if self.options.serialize_none {
139            none(self.ctx).into()
140        } else {
141            Value::Nil
142        })
143    }
144
145    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value<'gc>, Error>
146    where
147        T: serde::Serialize,
148    {
149        value.serialize(self)
150    }
151
152    fn serialize_unit(self) -> Result<Value<'gc>, Error> {
153        Ok(unit(self.ctx).into())
154    }
155
156    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value<'gc>, Error> {
157        self.serialize_unit()
158    }
159
160    fn serialize_unit_variant(
161        self,
162        _name: &'static str,
163        _variant_index: u32,
164        variant: &'static str,
165    ) -> Result<Value<'gc>, Error> {
166        self.serialize_str(variant)
167    }
168
169    fn serialize_newtype_struct<T: ?Sized>(
170        self,
171        _name: &'static str,
172        value: &T,
173    ) -> Result<Value<'gc>, Error>
174    where
175        T: serde::Serialize,
176    {
177        value.serialize(self)
178    }
179
180    fn serialize_newtype_variant<T: ?Sized>(
181        self,
182        _name: &'static str,
183        _variant_index: u32,
184        variant: &'static str,
185        value: &T,
186    ) -> Result<Value<'gc>, Error>
187    where
188        T: serde::Serialize,
189    {
190        let value = value.serialize(self)?;
191        let table = Table::new(&self.ctx);
192        table.set(self.ctx, variant, value).unwrap();
193        Ok(table.into())
194    }
195
196    fn serialize_seq(self, _len: Option<usize>) -> Result<SerializeSeq<'gc>, Error> {
197        Ok(SerializeSeq::new(self.ctx, self.options))
198    }
199
200    fn serialize_tuple(self, len: usize) -> Result<SerializeSeq<'gc>, Error> {
201        self.serialize_seq(Some(len))
202    }
203
204    fn serialize_tuple_struct(
205        self,
206        _name: &'static str,
207        len: usize,
208    ) -> Result<SerializeSeq<'gc>, Error> {
209        self.serialize_seq(Some(len))
210    }
211
212    fn serialize_tuple_variant(
213        self,
214        _name: &'static str,
215        _variant_index: u32,
216        variant: &'static str,
217        _len: usize,
218    ) -> Result<Self::SerializeTupleVariant, Error> {
219        Ok(SerializeTupleVariant::new(self.ctx, self.options, variant))
220    }
221
222    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
223        Ok(SerializeMap::new(self.ctx, self.options))
224    }
225
226    fn serialize_struct(
227        self,
228        _name: &'static str,
229        _len: usize,
230    ) -> Result<Self::SerializeStruct, Error> {
231        Ok(SerializeStruct::new(self.ctx, self.options))
232    }
233
234    fn serialize_struct_variant(
235        self,
236        _name: &'static str,
237        _variant_index: u32,
238        variant: &'static str,
239        _len: usize,
240    ) -> Result<Self::SerializeStructVariant, Error> {
241        Ok(SerializeStructVariant::new(self.ctx, self.options, variant))
242    }
243}
244
245pub struct SerializeSeq<'gc> {
246    ctx: Context<'gc>,
247    options: Options,
248    table: Table<'gc>,
249    ind: i64,
250}
251
252impl<'gc> SerializeSeq<'gc> {
253    pub fn new(ctx: Context<'gc>, options: Options) -> Self {
254        Self {
255            ctx,
256            options,
257            table: Table::new(&ctx),
258            ind: 1,
259        }
260    }
261}
262
263impl<'gc> ser::SerializeSeq for SerializeSeq<'gc> {
264    type Ok = Value<'gc>;
265    type Error = Error;
266
267    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
268    where
269        T: serde::Serialize,
270    {
271        self.table
272            .set(
273                self.ctx,
274                self.ind,
275                value.serialize(Serializer::new(self.ctx, self.options))?,
276            )
277            .unwrap();
278        self.ind = self
279            .ind
280            .checked_add(1)
281            .ok_or(ser::Error::custom("index overflow"))?;
282        Ok(())
283    }
284
285    fn end(self) -> Result<Value<'gc>, Error> {
286        Ok(self.table.into())
287    }
288}
289
290impl<'gc> ser::SerializeTuple for SerializeSeq<'gc> {
291    type Ok = Value<'gc>;
292    type Error = Error;
293
294    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
295    where
296        T: serde::Serialize,
297    {
298        ser::SerializeSeq::serialize_element(self, value)
299    }
300
301    fn end(self) -> Result<Value<'gc>, Error> {
302        ser::SerializeSeq::end(self)
303    }
304}
305
306impl<'gc> ser::SerializeTupleStruct for SerializeSeq<'gc> {
307    type Ok = Value<'gc>;
308    type Error = Error;
309
310    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
311    where
312        T: serde::Serialize,
313    {
314        ser::SerializeSeq::serialize_element(self, value)
315    }
316
317    fn end(self) -> Result<Value<'gc>, Error> {
318        ser::SerializeSeq::end(self)
319    }
320}
321
322pub struct SerializeMap<'gc> {
323    ctx: Context<'gc>,
324    options: Options,
325    table: Table<'gc>,
326    next_key: Value<'gc>,
327}
328
329impl<'gc> SerializeMap<'gc> {
330    pub fn new(ctx: Context<'gc>, options: Options) -> Self {
331        Self {
332            ctx,
333            options,
334            table: Table::new(&ctx),
335            next_key: Value::Nil,
336        }
337    }
338}
339
340impl<'gc> ser::SerializeMap for SerializeMap<'gc> {
341    type Ok = Value<'gc>;
342    type Error = Error;
343
344    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
345    where
346        T: serde::Serialize,
347    {
348        self.next_key = key.serialize(Serializer::new(self.ctx, self.options))?;
349        Ok(())
350    }
351
352    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
353    where
354        T: serde::Serialize,
355    {
356        self.table
357            .set(
358                self.ctx,
359                self.next_key,
360                value.serialize(Serializer::new(self.ctx, self.options))?,
361            )
362            .map_err(|_| {
363                ser::Error::custom("key in map / struct must not serialize to Nil / NaN")
364            })?;
365        self.next_key = Value::Nil;
366        Ok(())
367    }
368
369    fn end(self) -> Result<Self::Ok, Self::Error> {
370        Ok(self.table.into())
371    }
372}
373
374pub struct SerializeStruct<'gc> {
375    ctx: Context<'gc>,
376    options: Options,
377    table: Table<'gc>,
378}
379
380impl<'gc> SerializeStruct<'gc> {
381    pub fn new(ctx: Context<'gc>, options: Options) -> Self {
382        Self {
383            ctx,
384            options,
385            table: Table::new(&ctx),
386        }
387    }
388}
389
390impl<'gc> ser::SerializeStruct for SerializeStruct<'gc> {
391    type Ok = Value<'gc>;
392    type Error = Error;
393
394    fn serialize_field<T: ?Sized>(
395        &mut self,
396        key: &'static str,
397        value: &T,
398    ) -> Result<(), Self::Error>
399    where
400        T: serde::Serialize,
401    {
402        self.table
403            .set(
404                self.ctx,
405                key,
406                value.serialize(Serializer::new(self.ctx, self.options))?,
407            )
408            .unwrap();
409        Ok(())
410    }
411
412    fn end(self) -> Result<Self::Ok, Self::Error> {
413        Ok(self.table.into())
414    }
415}
416
417pub struct SerializeTupleVariant<'gc> {
418    ctx: Context<'gc>,
419    options: Options,
420    variant: &'static str,
421    table: Table<'gc>,
422    ind: i64,
423}
424
425impl<'gc> SerializeTupleVariant<'gc> {
426    pub fn new(ctx: Context<'gc>, options: Options, variant: &'static str) -> Self {
427        Self {
428            ctx,
429            options,
430            variant,
431            table: Table::new(&ctx),
432            ind: 1,
433        }
434    }
435}
436
437impl<'gc> ser::SerializeTupleVariant for SerializeTupleVariant<'gc> {
438    type Ok = Value<'gc>;
439    type Error = Error;
440
441    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
442    where
443        T: serde::Serialize,
444    {
445        self.table
446            .set(
447                self.ctx,
448                self.ind,
449                value.serialize(Serializer::new(self.ctx, self.options))?,
450            )
451            .unwrap();
452        self.ind = self
453            .ind
454            .checked_add(1)
455            .ok_or(ser::Error::custom("index overflow"))?;
456        Ok(())
457    }
458
459    fn end(self) -> Result<Self::Ok, Self::Error> {
460        let enclosing = Table::new(&self.ctx);
461        enclosing.set(self.ctx, self.variant, self.table).unwrap();
462        Ok(enclosing.into())
463    }
464}
465
466pub struct SerializeStructVariant<'gc> {
467    ctx: Context<'gc>,
468    options: Options,
469    variant: &'static str,
470    table: Table<'gc>,
471}
472
473impl<'gc> SerializeStructVariant<'gc> {
474    pub fn new(ctx: Context<'gc>, options: Options, variant: &'static str) -> Self {
475        Self {
476            ctx,
477            options,
478            variant,
479            table: Table::new(&ctx),
480        }
481    }
482}
483
484impl<'gc> ser::SerializeStructVariant for SerializeStructVariant<'gc> {
485    type Ok = Value<'gc>;
486    type Error = Error;
487
488    fn serialize_field<T: ?Sized>(
489        &mut self,
490        key: &'static str,
491        value: &T,
492    ) -> Result<(), Self::Error>
493    where
494        T: serde::Serialize,
495    {
496        self.table
497            .set(
498                self.ctx,
499                key,
500                value.serialize(Serializer::new(self.ctx, self.options))?,
501            )
502            .unwrap();
503        Ok(())
504    }
505
506    fn end(self) -> Result<Self::Ok, Self::Error> {
507        let enclosing = Table::new(&self.ctx);
508        enclosing.set(self.ctx, self.variant, self.table).unwrap();
509        Ok(enclosing.into())
510    }
511}