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(feature = "serde")]
6pub mod serde;
7
8use crate::de::DeserializeSeed;
9use crate::{algebraic_value::ser::ValueSerializer, bsatn, buffer::BufWriter};
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 sum value provided the chosen `tag`, `name`, and `value`.
121 fn serialize_variant<T: Serialize + ?Sized>(
122 self,
123 tag: u8,
124 name: Option<&str>,
125 value: &T,
126 ) -> Result<Self::Ok, Self::Error>;
127
128 /// Serialize the given `bsatn` encoded data of type `ty`.
129 ///
130 /// This is a concession to performance,
131 /// allowing some implementations to write the buffer directly.
132 ///
133 /// # Safety
134 ///
135 /// - `decode(ty, &mut bsatn).is_ok()`.
136 /// That is, `bsatn` encodes a valid element of `ty`.
137 /// It's up to the caller to arrange `Ty` such that this holds.
138 unsafe fn serialize_bsatn<Ty>(self, ty: &Ty, bsatn: &[u8]) -> Result<Self::Ok, Self::Error>
139 where
140 for<'a, 'de> WithTypespace<'a, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
141 {
142 // TODO(Centril): Consider instead deserializing the `bsatn` through a
143 // deserializer that serializes into `self` directly.
144
145 // First convert the BSATN to an `AlgebraicValue`.
146 // SAFETY: Forward caller requirements of this method to that we are calling.
147 let res = unsafe { ValueSerializer.serialize_bsatn(ty, bsatn) };
148 let value = res.unwrap_or_else(|x| match x {});
149
150 // Then serialize that.
151 value.serialize(self)
152 }
153
154 /// Serialize the given `bsatn` encoded data of type `ty`.
155 ///
156 /// The data is provided as an iterator of chunks, at arbitrary boundaries,
157 /// with a total concatenated length of `total_bsatn_len` which callers can assume.
158 ///
159 /// An implementation of this method is semantically the same as:
160 /// ```rust,ignore
161 /// let mut buf = Vec::new();
162 /// for chunk in bsatn {
163 /// buf.extend(chunk);
164 /// }
165 /// ser.serialize_bsatn(&buf);
166 /// ```
167 ///
168 /// This method is a concession to performance,
169 /// allowing some implementations to write the buffer directly.
170 ///
171 /// The parameter `I` is required to be `Clone` only for `debug_assert!` purposes.
172 ///
173 /// # Safety
174 ///
175 /// - `total_bsatn_len == bsatn.map(|c| c.len()).sum() <= isize::MAX`
176 /// - Let `buf` be defined as above, i.e., the bytes of `bsatn` concatenated.
177 /// Then `decode(ty, &mut buf).is_ok()`.
178 /// That is, `buf` encodes a valid element of `ty`.
179 /// It's up to the caller to arrange `Ty` such that this holds.
180 unsafe fn serialize_bsatn_in_chunks<'a, Ty, I: Clone + Iterator<Item = &'a [u8]>>(
181 self,
182 ty: &Ty,
183 total_bsatn_len: usize,
184 bsatn: I,
185 ) -> Result<Self::Ok, Self::Error>
186 where
187 for<'b, 'de> WithTypespace<'b, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
188 {
189 // TODO(Centril): Unlike above, in this case we must at minimum concatenate `bsatn`
190 // before we can do the piping mentioned above, but that's better than
191 // serializing to `AlgebraicValue` first, so consider that.
192
193 // First convert the BSATN to an `AlgebraicValue`.
194 // SAFETY: Forward caller requirements of this method to that we are calling.
195 let res = unsafe { ValueSerializer.serialize_bsatn_in_chunks(ty, total_bsatn_len, bsatn) };
196 let value = res.unwrap_or_else(|x| match x {});
197
198 // Then serialize that.
199 value.serialize(self)
200 }
201
202 /// Serialize the given `string`.
203 ///
204 /// The string is provided as an iterator of chunks, at arbitrary boundaries,
205 /// with a total concatenated length of `total_len` which callers can trust.
206 ///
207 /// An implementation of this method is semantically the same as:
208 /// ```rust,ignore
209 /// let mut buf = Vec::new();
210 /// for chunk in string {
211 /// buf.extend(chunk);
212 /// }
213 /// let str = unsafe { core::str::from_utf8_unchecked(&buf) };
214 /// ser.serialize_str(str);
215 /// ```
216 ///
217 /// This method is a concession to performance,
218 /// allowing some implementations to write the buffer directly.
219 ///
220 /// The parameter `I` is required to be `Clone` only for `debug_assert!` purposes.
221 ///
222 /// # Safety
223 ///
224 /// - `total_len == string.map(|c| c.len()).sum() <= isize::MAX`
225 /// - Let `buf` be the bytes of `string` concatenated.
226 /// Then `core::str::from_utf8(&buf).is_ok()`.
227 /// That is, `buf` is valid UTF-8.
228 /// Note however that individual chunks need not be valid UTF-8,
229 /// as multi-byte characters may be split across chunk boundaries.
230 unsafe fn serialize_str_in_chunks<'a, I: Clone + Iterator<Item = &'a [u8]>>(
231 self,
232 total_len: usize,
233 string: I,
234 ) -> Result<Self::Ok, Self::Error> {
235 // First convert the `string` to an `AlgebraicValue`.
236 // SAFETY: Forward caller requirements of this method to that we are calling.
237 let res = unsafe { ValueSerializer.serialize_str_in_chunks(total_len, string) };
238 let value = res.unwrap_or_else(|x| match x {});
239
240 // Then serialize that.
241 // This incurs a very minor cost of branching on `AlgebraicValue::String`.
242 value.serialize(self)
243 }
244}
245
246/// A **data structure** that can be serialized into any data format supported by
247/// the SpacetimeDB Algebraic Type System.
248///
249/// In most cases, implementations of `Serialize` may be `#[derive(Serialize)]`d.
250///
251/// The `Serialize` trait in SATS performs the same function as `serde::Serialize` in [`serde`].
252/// See the documentation of `serde::Serialize` for more information of the data model.
253///
254/// Do not manually implement this trait unless you know what you are doing.
255/// Implementations must be consistent with `Deerialize<'de> for T`, `SpacetimeType for T` and `Serialize, Deserialize for AlgebraicValue`.
256/// Implementations that are inconsistent across these traits may result in data loss.
257///
258/// [`serde`]: https://crates.io/crates/serde
259pub trait Serialize {
260 /// Serialize `self` in the data format of `S` using the provided `serializer`.
261 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
262
263 #[doc(hidden)]
264 /// Serialize `self` in the data format BSATN using the provided BSATN `serializer`.
265 fn serialize_into_bsatn<W: BufWriter>(
266 &self,
267 serializer: bsatn::Serializer<'_, W>,
268 ) -> Result<(), bsatn::EncodeError> {
269 self.serialize(serializer)
270 }
271
272 /// Used in the `Serialize for Vec<T>` implementation
273 /// to allow a specialized serialization of `Vec<T>` as bytes.
274 #[doc(hidden)]
275 #[inline(always)]
276 fn __serialize_array<S: Serializer>(this: &[Self], serializer: S) -> Result<S::Ok, S::Error>
277 where
278 Self: Sized,
279 {
280 let mut vec = serializer.serialize_array(this.len())?;
281 for elem in this {
282 vec.serialize_element(elem)?;
283 }
284 vec.end()
285 }
286}
287
288/// The base trait serialization error types must implement.
289pub trait Error {
290 /// Returns an error derived from `msg: impl Display`.
291 fn custom<T: fmt::Display>(msg: T) -> Self;
292}
293
294impl Error for String {
295 fn custom<T: fmt::Display>(msg: T) -> Self {
296 msg.to_string()
297 }
298}
299
300impl Error for std::convert::Infallible {
301 fn custom<T: fmt::Display>(msg: T) -> Self {
302 panic!("error generated for Infallible serializer: {msg}")
303 }
304}
305
306/// Returned from [`Serializer::serialize_array`].
307///
308/// This provides a continuation of sorts
309/// where you can call [`serialize_element`](SerializeArray::serialize_element) however many times
310/// and then finally the [`end`](SerializeArray::end) is reached.
311pub trait SerializeArray {
312 /// Must match the `Ok` type of any `Serializer` that uses this type.
313 type Ok;
314
315 /// Must match the `Error` type of any `Serializer` that uses this type.
316 type Error: Error;
317
318 /// Serialize an array `element`.
319 fn serialize_element<T: Serialize + ?Sized>(&mut self, element: &T) -> Result<(), Self::Error>;
320
321 /// Consumes and finalizes the array serializer returning the `Self::Ok` data.
322 fn end(self) -> Result<Self::Ok, Self::Error>;
323}
324
325/// Returned from [`Serializer::serialize_seq_product`].
326///
327/// This provides a continuation of sorts
328/// where you can call [`serialize_element`](SerializeSeqProduct::serialize_element) however many times
329/// and then finally the [`end`](SerializeSeqProduct::end) is reached.
330pub trait SerializeSeqProduct {
331 /// Must match the `Ok` type of any `Serializer` that uses this type.
332 type Ok;
333
334 /// Must match the `Error` type of any `Serializer` that uses this type.
335 type Error: Error;
336
337 /// Serialize an unnamed product `element`.
338 fn serialize_element<T: Serialize + ?Sized>(&mut self, element: &T) -> Result<(), Self::Error>;
339
340 /// Consumes and finalizes the product serializer returning the `Self::Ok` data.
341 fn end(self) -> Result<Self::Ok, Self::Error>;
342}
343
344/// Returned from [`Serializer::serialize_named_product`].
345///
346/// This provides a continuation of sorts
347/// where you can call [`serialize_element`](SerializeNamedProduct::serialize_element) however many times
348/// and then finally the [`end`](SerializeNamedProduct::end) is reached.
349pub trait SerializeNamedProduct {
350 /// Must match the `Ok` type of any `Serializer` that uses this type.
351 type Ok;
352
353 /// Must match the `Error` type of any `Serializer` that uses this type.
354 type Error: Error;
355
356 /// Serialize a named product `element` with `name`.
357 fn serialize_element<T: Serialize + ?Sized>(&mut self, name: Option<&str>, elem: &T) -> Result<(), Self::Error>;
358
359 /// Consumes and finalizes the product serializer returning the `Self::Ok` data.
360 fn end(self) -> Result<Self::Ok, Self::Error>;
361}
362
363/// Forwards the implementation of a named product value
364/// to the implementation of the unnamed kind,
365/// thereby ignoring any field names.
366pub struct ForwardNamedToSeqProduct<S> {
367 /// The unnamed product serializer.
368 tup: S,
369}
370
371impl<S> ForwardNamedToSeqProduct<S> {
372 /// Returns a forwarder based on the provided unnamed product serializer.
373 pub fn new(tup: S) -> Self {
374 Self { tup }
375 }
376
377 /// Forwards the serialization of a named product of `len` fields
378 /// to an unnamed serialization format.
379 pub fn forward<Ser>(ser: Ser, len: usize) -> Result<Self, Ser::Error>
380 where
381 Ser: Serializer<SerializeSeqProduct = S>,
382 {
383 ser.serialize_seq_product(len).map(Self::new)
384 }
385}
386
387impl<S: SerializeSeqProduct> SerializeNamedProduct for ForwardNamedToSeqProduct<S> {
388 type Ok = S::Ok;
389 type Error = S::Error;
390
391 fn serialize_element<T: Serialize + ?Sized>(&mut self, _name: Option<&str>, elem: &T) -> Result<(), Self::Error> {
392 self.tup.serialize_element(elem)
393 }
394
395 fn end(self) -> Result<Self::Ok, Self::Error> {
396 self.tup.end()
397 }
398}
399
400/// A type usable in one of the associated types of [`Serializer`]
401/// when the data format does not support the data.
402pub struct Impossible<Ok, Error> {
403 // They gave each other a pledge. Unheard of, absurd.
404 absurd: Infallible,
405 marker: PhantomData<(Ok, Error)>,
406}
407
408impl<Ok, Error: self::Error> SerializeArray for Impossible<Ok, Error> {
409 type Ok = Ok;
410 type Error = Error;
411
412 fn serialize_element<T: Serialize + ?Sized>(&mut self, _: &T) -> Result<(), Self::Error> {
413 match self.absurd {}
414 }
415
416 fn end(self) -> Result<Self::Ok, Self::Error> {
417 match self.absurd {}
418 }
419}
420
421impl<Ok, Error: self::Error> SerializeSeqProduct for Impossible<Ok, Error> {
422 type Ok = Ok;
423 type Error = Error;
424
425 fn serialize_element<T: Serialize + ?Sized>(&mut self, _: &T) -> Result<(), Self::Error> {
426 match self.absurd {}
427 }
428
429 fn end(self) -> Result<Self::Ok, Self::Error> {
430 match self.absurd {}
431 }
432}
433
434impl<Ok, Error: self::Error> SerializeNamedProduct for Impossible<Ok, Error> {
435 type Ok = Ok;
436 type Error = Error;
437
438 fn serialize_element<T: Serialize + ?Sized>(&mut self, _: Option<&str>, _: &T) -> Result<(), Self::Error> {
439 match self.absurd {}
440 }
441
442 fn end(self) -> Result<Self::Ok, Self::Error> {
443 match self.absurd {}
444 }
445}