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 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}