Skip to main content

spacetimedb_sats/
ser.rs

1// Some parts copyright Serde developers under the MIT / Apache-2.0 licenses at your option.
2// See `serde` version `v1.0.169` for the parts where MIT / Apache-2.0 applies.
3
4mod impls;
5#[cfg(any(test, feature = "serde"))]
6pub mod serde;
7
8use crate::de::DeserializeSeed;
9use crate::{algebraic_value::ser::ValueSerializer, bsatn, buffer::BufWriter, ProductValue, SumValue, ValueWithType};
10use crate::{AlgebraicValue, WithTypespace};
11use core::marker::PhantomData;
12use core::{convert::Infallible, fmt};
13use ethnum::{i256, u256};
14pub use spacetimedb_bindings_macro::Serialize;
15
16/// A data format that can deserialize any data structure supported by SATs.
17///
18/// The `Serializer` trait in SATS performs the same function as `serde::Serializer` in [`serde`].
19/// See the documentation of `serde::Serializer` for more information on the data model.
20///
21/// [`serde`]: https://crates.io/crates/serde
22pub trait Serializer: Sized {
23    /// The output type produced by this `Serializer` during successful serialization.
24    ///
25    /// Most serializers that produce text or binary output should set `Ok = ()`
26    /// and serialize into an [`io::Write`] or buffer contained within the `Serializer` instance.
27    /// Serializers that build in-memory data structures may be simplified by using `Ok` to propagate
28    /// the data structure around.
29    ///
30    /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
31    type Ok;
32
33    /// The error type when some error occurs during serialization.
34    type Error: Error;
35
36    /// Type returned from [`serialize_array`](Serializer::serialize_array)
37    /// for serializing the contents of the array.
38    type SerializeArray: SerializeArray<Ok = Self::Ok, Error = Self::Error>;
39
40    /// Type returned from [`serialize_seq_product`](Serializer::serialize_seq_product)
41    /// for serializing the contents of the *unnamed* product.
42    type SerializeSeqProduct: SerializeSeqProduct<Ok = Self::Ok, Error = Self::Error>;
43
44    /// Type returned from [`serialize_named_product`](Serializer::serialize_named_product)
45    /// for serializing the contents of the *named* product.
46    type SerializeNamedProduct: SerializeNamedProduct<Ok = Self::Ok, Error = Self::Error>;
47
48    /// Serialize a `bool` value.
49    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
50
51    /// Serialize a `u8` value.
52    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
53
54    /// Serialize a `u16` value.
55    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
56
57    /// Serialize a `u32` value.
58    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
59
60    /// Serialize a `u64` value.
61    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
62
63    /// Serialize a `u128` value.
64    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error>;
65
66    /// Serialize a `u256` value.
67    fn serialize_u256(self, v: u256) -> Result<Self::Ok, Self::Error>;
68
69    /// Serialize an `i8` value.
70    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
71
72    /// Serialize an `i16` value.
73    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
74
75    /// Serialize an `i32` value.
76    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
77
78    /// Serialize an `i64` value.
79    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
80
81    /// Serialize an `i128` value.
82    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error>;
83
84    /// Serialize an `i256` value.
85    fn serialize_i256(self, v: i256) -> Result<Self::Ok, Self::Error>;
86
87    /// Serialize an `f32` value.
88    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
89
90    /// Serialize an `f64` value.
91    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
92
93    /// Serialize a `&str` string slice.
94    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>;
95
96    /// Serialize a `&[u8]` byte slice.
97    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>;
98
99    /// Begin to serialize a variably sized array.
100    /// This call must be followed by zero or more calls to [`SerializeArray::serialize_element`],
101    /// then a call to [`SerializeArray::end`].
102    ///
103    /// The argument is the number of elements in the sequence.
104    fn serialize_array(self, len: usize) -> Result<Self::SerializeArray, Self::Error>;
105
106    /// Begin to serialize a product with unnamed fields.
107    /// This call must be followed by zero or more calls to [`SerializeSeqProduct::serialize_element`],
108    /// then a call to [`SerializeSeqProduct::end`].
109    ///
110    /// The argument is the number of fields in the product.
111    fn serialize_seq_product(self, len: usize) -> Result<Self::SerializeSeqProduct, Self::Error>;
112
113    /// Begin to serialize a product with named fields.
114    /// This call must be followed by zero or more calls to [`SerializeNamedProduct::serialize_element`],
115    /// then a call to [`SerializeNamedProduct::end`].
116    ///
117    /// The argument is the number of fields in the product.
118    fn serialize_named_product(self, len: usize) -> Result<Self::SerializeNamedProduct, Self::Error>;
119
120    /// Serialize a product with named fields.
121    ///
122    /// Allow to override the default serialization for where we need to switch the output format,
123    /// see [`crate::satn::TypedWriter`].
124    fn serialize_named_product_raw(self, value: &ValueWithType<'_, ProductValue>) -> Result<Self::Ok, Self::Error> {
125        let val = &value.val.elements;
126        assert_eq!(val.len(), value.ty().elements.len());
127        let mut prod = self.serialize_named_product(val.len())?;
128        for (val, el_ty) in val.iter().zip(&*value.ty().elements) {
129            prod.serialize_element(el_ty.name().map(|n| &**n), &value.with(&el_ty.algebraic_type, val))?
130        }
131        prod.end()
132    }
133
134    /// Serialize a sum value
135    ///
136    /// Allow to override the default serialization for where we need to switch the output format,
137    /// see [`crate::satn::TypedWriter`].
138    fn serialize_variant_raw(self, sum: &ValueWithType<'_, SumValue>) -> Result<Self::Ok, Self::Error> {
139        let sv = sum.value();
140        let (tag, val) = (sv.tag, &*sv.value);
141        let var_ty = &sum.ty().variants[tag as usize]; // Extract the variant type by tag.
142        self.serialize_variant(tag, var_ty.name().map(|n| &**n), &sum.with(&var_ty.algebraic_type, val))
143    }
144
145    /// Serialize a sum value provided the chosen `tag`, `name`, and `value`.
146    fn serialize_variant<T: Serialize + ?Sized>(
147        self,
148        tag: u8,
149        name: Option<&str>,
150        value: &T,
151    ) -> Result<Self::Ok, Self::Error>;
152
153    /// Serialize the given `bsatn` encoded data of type `ty`.
154    ///
155    /// This is a concession to performance,
156    /// allowing some implementations to write the buffer directly.
157    ///
158    /// # Safety
159    ///
160    /// - `decode(ty, &mut bsatn).is_ok()`.
161    ///   That is, `bsatn` encodes a valid element of `ty`.
162    ///   It's up to the caller to arrange `Ty` such that this holds.
163    unsafe fn serialize_bsatn<Ty>(self, ty: &Ty, bsatn: &[u8]) -> Result<Self::Ok, Self::Error>
164    where
165        for<'a, 'de> WithTypespace<'a, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
166    {
167        // TODO(Centril): Consider instead deserializing the `bsatn` through a
168        // deserializer that serializes into `self` directly.
169
170        // First convert the BSATN to an `AlgebraicValue`.
171        // SAFETY: Forward caller requirements of this method to that we are calling.
172        let res = unsafe { ValueSerializer.serialize_bsatn(ty, bsatn) };
173        let value = res.unwrap_or_else(|x| match x {});
174
175        // Then serialize that.
176        value.serialize(self)
177    }
178
179    /// Serialize the given `bsatn` encoded data of type `ty`.
180    ///
181    /// The data is provided as an iterator of chunks, at arbitrary boundaries,
182    /// with a total concatenated length of `total_bsatn_len` which callers can assume.
183    ///
184    /// An implementation of this method is semantically the same as:
185    /// ```rust,ignore
186    /// let mut buf = Vec::new();
187    /// for chunk in bsatn {
188    ///     buf.extend(chunk);
189    /// }
190    /// ser.serialize_bsatn(&buf);
191    /// ```
192    ///
193    /// This method is a concession to performance,
194    /// allowing some implementations to write the buffer directly.
195    ///
196    /// The parameter `I` is required to be `Clone` only for `debug_assert!` purposes.
197    ///
198    /// # Safety
199    ///
200    /// - `total_bsatn_len == bsatn.map(|c| c.len()).sum() <= isize::MAX`
201    /// - Let `buf` be defined as above, i.e., the bytes of `bsatn` concatenated.
202    ///   Then `decode(ty, &mut buf).is_ok()`.
203    ///   That is, `buf` encodes a valid element of `ty`.
204    ///   It's up to the caller to arrange `Ty` such that this holds.
205    unsafe fn serialize_bsatn_in_chunks<'a, Ty, I: Clone + Iterator<Item = &'a [u8]>>(
206        self,
207        ty: &Ty,
208        total_bsatn_len: usize,
209        bsatn: I,
210    ) -> Result<Self::Ok, Self::Error>
211    where
212        for<'b, 'de> WithTypespace<'b, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
213    {
214        // TODO(Centril): Unlike above, in this case we must at minimum concatenate `bsatn`
215        // before we can do the piping mentioned above, but that's better than
216        // serializing to `AlgebraicValue` first, so consider that.
217
218        // First convert the BSATN to an `AlgebraicValue`.
219        // SAFETY: Forward caller requirements of this method to that we are calling.
220        let res = unsafe { ValueSerializer.serialize_bsatn_in_chunks(ty, total_bsatn_len, bsatn) };
221        let value = res.unwrap_or_else(|x| match x {});
222
223        // Then serialize that.
224        value.serialize(self)
225    }
226
227    /// Serialize the given `string`.
228    ///
229    /// The string is provided as an iterator of chunks, at arbitrary boundaries,
230    /// with a total concatenated length of `total_len` which callers can trust.
231    ///
232    /// An implementation of this method is semantically the same as:
233    /// ```rust,ignore
234    /// let mut buf = Vec::new();
235    /// for chunk in string {
236    ///     buf.extend(chunk);
237    /// }
238    /// let str = unsafe { core::str::from_utf8_unchecked(&buf) };
239    /// ser.serialize_str(str);
240    /// ```
241    ///
242    /// This method is a concession to performance,
243    /// allowing some implementations to write the buffer directly.
244    ///
245    /// The parameter `I` is required to be `Clone` only for `debug_assert!` purposes.
246    ///
247    /// # Safety
248    ///
249    /// - `total_len == string.map(|c| c.len()).sum() <= isize::MAX`
250    /// - Let `buf` be the bytes of `string` concatenated.
251    ///   Then `core::str::from_utf8(&buf).is_ok()`.
252    ///   That is, `buf` is valid UTF-8.
253    ///   Note however that individual chunks need not be valid UTF-8,
254    ///   as multi-byte characters may be split across chunk boundaries.
255    unsafe fn serialize_str_in_chunks<'a, I: Clone + Iterator<Item = &'a [u8]>>(
256        self,
257        total_len: usize,
258        string: I,
259    ) -> Result<Self::Ok, Self::Error> {
260        // First convert the `string` to an `AlgebraicValue`.
261        // SAFETY: Forward caller requirements of this method to that we are calling.
262        let res = unsafe { ValueSerializer.serialize_str_in_chunks(total_len, string) };
263        let value = res.unwrap_or_else(|x| match x {});
264
265        // Then serialize that.
266        // This incurs a very minor cost of branching on `AlgebraicValue::String`.
267        value.serialize(self)
268    }
269}
270
271/// A **data structure** that can be serialized into any data format supported by
272/// the SpacetimeDB Algebraic Type System.
273///
274/// In most cases, implementations of `Serialize` may be `#[derive(Serialize)]`d.
275///
276/// The `Serialize` trait in SATS performs the same function as `serde::Serialize` in [`serde`].
277/// See the documentation of `serde::Serialize` for more information of the data model.
278///
279/// Do not manually implement this trait unless you know what you are doing.
280/// Implementations must be consistent with `Deerialize<'de> for T`, `SpacetimeType for T` and `Serialize, Deserialize for AlgebraicValue`.
281/// Implementations that are inconsistent across these traits may result in data loss.
282///
283/// [`serde`]: https://crates.io/crates/serde
284pub trait Serialize {
285    /// Serialize `self` in the data format of `S` using the provided `serializer`.
286    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
287
288    #[doc(hidden)]
289    /// Serialize `self` in the data format BSATN using the provided BSATN `serializer`.
290    fn serialize_into_bsatn<W: BufWriter>(
291        &self,
292        serializer: bsatn::Serializer<'_, W>,
293    ) -> Result<(), bsatn::EncodeError> {
294        self.serialize(serializer)
295    }
296
297    /// Used in the `Serialize for Vec<T>` implementation
298    /// to allow a specialized serialization of `Vec<T>` as bytes.
299    #[doc(hidden)]
300    #[inline(always)]
301    fn __serialize_array<S: Serializer>(this: &[Self], serializer: S) -> Result<S::Ok, S::Error>
302    where
303        Self: Sized,
304    {
305        let mut vec = serializer.serialize_array(this.len())?;
306        for elem in this {
307            vec.serialize_element(elem)?;
308        }
309        vec.end()
310    }
311}
312
313/// The base trait serialization error types must implement.
314pub trait Error {
315    /// Returns an error derived from `msg: impl Display`.
316    fn custom<T: fmt::Display>(msg: T) -> Self;
317}
318
319impl Error for String {
320    fn custom<T: fmt::Display>(msg: T) -> Self {
321        msg.to_string()
322    }
323}
324
325impl Error for std::convert::Infallible {
326    fn custom<T: fmt::Display>(msg: T) -> Self {
327        panic!("error generated for Infallible serializer: {msg}")
328    }
329}
330
331/// Returned from [`Serializer::serialize_array`].
332///
333/// This provides a continuation of sorts
334/// where you can call [`serialize_element`](SerializeArray::serialize_element) however many times
335/// and then finally the [`end`](SerializeArray::end) is reached.
336pub trait SerializeArray {
337    /// Must match the `Ok` type of any `Serializer` that uses this type.
338    type Ok;
339
340    /// Must match the `Error` type of any `Serializer` that uses this type.
341    type Error: Error;
342
343    /// Serialize an array `element`.
344    fn serialize_element<T: Serialize + ?Sized>(&mut self, element: &T) -> Result<(), Self::Error>;
345
346    /// Consumes and finalizes the array serializer returning the `Self::Ok` data.
347    fn end(self) -> Result<Self::Ok, Self::Error>;
348}
349
350/// Returned from [`Serializer::serialize_seq_product`].
351///
352/// This provides a continuation of sorts
353/// where you can call [`serialize_element`](SerializeSeqProduct::serialize_element) however many times
354/// and then finally the [`end`](SerializeSeqProduct::end) is reached.
355pub trait SerializeSeqProduct {
356    /// Must match the `Ok` type of any `Serializer` that uses this type.
357    type Ok;
358
359    /// Must match the `Error` type of any `Serializer` that uses this type.
360    type Error: Error;
361
362    /// Serialize an unnamed product `element`.
363    fn serialize_element<T: Serialize + ?Sized>(&mut self, element: &T) -> Result<(), Self::Error>;
364
365    /// Consumes and finalizes the product serializer returning the `Self::Ok` data.
366    fn end(self) -> Result<Self::Ok, Self::Error>;
367}
368
369/// Returned from [`Serializer::serialize_named_product`].
370///
371/// This provides a continuation of sorts
372/// where you can call [`serialize_element`](SerializeNamedProduct::serialize_element) however many times
373/// and then finally the [`end`](SerializeNamedProduct::end) is reached.
374pub trait SerializeNamedProduct {
375    /// Must match the `Ok` type of any `Serializer` that uses this type.
376    type Ok;
377
378    /// Must match the `Error` type of any `Serializer` that uses this type.
379    type Error: Error;
380
381    /// Serialize a named product `element` with `name`.
382    fn serialize_element<T: Serialize + ?Sized>(&mut self, name: Option<&str>, elem: &T) -> Result<(), Self::Error>;
383
384    /// Consumes and finalizes the product serializer returning the `Self::Ok` data.
385    fn end(self) -> Result<Self::Ok, Self::Error>;
386}
387
388/// Forwards the implementation of a named product value
389/// to the implementation of the unnamed kind,
390/// thereby ignoring any field names.
391pub struct ForwardNamedToSeqProduct<S> {
392    /// The unnamed product serializer.
393    tup: S,
394}
395
396impl<S> ForwardNamedToSeqProduct<S> {
397    /// Returns a forwarder based on the provided unnamed product serializer.
398    pub fn new(tup: S) -> Self {
399        Self { tup }
400    }
401
402    /// Forwards the serialization of a named product of `len` fields
403    /// to an unnamed serialization format.
404    pub fn forward<Ser>(ser: Ser, len: usize) -> Result<Self, Ser::Error>
405    where
406        Ser: Serializer<SerializeSeqProduct = S>,
407    {
408        ser.serialize_seq_product(len).map(Self::new)
409    }
410}
411
412impl<S: SerializeSeqProduct> SerializeNamedProduct for ForwardNamedToSeqProduct<S> {
413    type Ok = S::Ok;
414    type Error = S::Error;
415
416    fn serialize_element<T: Serialize + ?Sized>(&mut self, _name: Option<&str>, elem: &T) -> Result<(), Self::Error> {
417        self.tup.serialize_element(elem)
418    }
419
420    fn end(self) -> Result<Self::Ok, Self::Error> {
421        self.tup.end()
422    }
423}
424
425/// A type usable in one of the associated types of [`Serializer`]
426/// when the data format does not support the data.
427pub struct Impossible<Ok, Error> {
428    // They gave each other a pledge. Unheard of, absurd.
429    absurd: Infallible,
430    marker: PhantomData<(Ok, Error)>,
431}
432
433impl<Ok, Error: self::Error> SerializeArray for Impossible<Ok, Error> {
434    type Ok = Ok;
435    type Error = Error;
436
437    fn serialize_element<T: Serialize + ?Sized>(&mut self, _: &T) -> Result<(), Self::Error> {
438        match self.absurd {}
439    }
440
441    fn end(self) -> Result<Self::Ok, Self::Error> {
442        match self.absurd {}
443    }
444}
445
446impl<Ok, Error: self::Error> SerializeSeqProduct for Impossible<Ok, Error> {
447    type Ok = Ok;
448    type Error = Error;
449
450    fn serialize_element<T: Serialize + ?Sized>(&mut self, _: &T) -> Result<(), Self::Error> {
451        match self.absurd {}
452    }
453
454    fn end(self) -> Result<Self::Ok, Self::Error> {
455        match self.absurd {}
456    }
457}
458
459impl<Ok, Error: self::Error> SerializeNamedProduct for Impossible<Ok, Error> {
460    type Ok = Ok;
461    type Error = Error;
462
463    fn serialize_element<T: Serialize + ?Sized>(&mut self, _: Option<&str>, _: &T) -> Result<(), Self::Error> {
464        match self.absurd {}
465    }
466
467    fn end(self) -> Result<Self::Ok, Self::Error> {
468        match self.absurd {}
469    }
470}