spacetimedb_sats/ser/
impls.rs

1use super::{Serialize, SerializeArray, SerializeNamedProduct, SerializeSeqProduct, Serializer};
2use crate::{i256, u256};
3use crate::{AlgebraicType, AlgebraicValue, ArrayValue, ProductValue, SumValue, ValueWithType, F32, F64};
4use core::ops::Bound;
5use smallvec::SmallVec;
6use spacetimedb_primitives::{ColList, ColSet};
7use std::rc::Rc;
8use std::sync::Arc;
9
10/// Implements [`Serialize`] for a type in a simplified manner.
11///
12/// An example:
13/// ```ignore
14/// struct Foo<'a, T: Copy>(&'a T, u8);
15/// impl_serialize!(
16/// //     Type parameters  Optional where  Impl type
17/// //            v               v             v
18/// //   ----------------  --------------- ----------
19///     ['a, T: Serialize] where [T: Copy] Foo<'a, T>,
20/// //  The `serialize` implementation where `self` is serialized into `ser`
21/// //  and the expression right of `=>` is the body of `serialize`.
22///     (self, ser) => {
23///         let mut prod = ser.serialize_seq_product(2)?;
24///         prod.serialize_element(&self.0)?;
25///         prod.serialize_element(&self.1)?;
26///         prod.end()
27///     }
28/// );
29/// ```
30#[macro_export]
31macro_rules! impl_serialize {
32    ([$($generics:tt)*] $(where [$($wc:tt)*])? $typ:ty, ($self:ident, $ser:ident) => $body:expr) => {
33        impl<$($generics)*> $crate::ser::Serialize for $typ $(where $($wc)*)? {
34            fn serialize<S: $crate::ser::Serializer>($self: &Self, $ser: S) -> Result<S::Ok, S::Error> {
35                $body
36            }
37        }
38    };
39}
40
41macro_rules! impl_prim {
42    ($(($prim:ty, $method:ident))*) => {
43        $(impl_serialize!([] $prim, (self, ser) => ser.$method((*self).into()));)*
44    };
45}
46
47impl_serialize!([] (), (self, ser) => ser.serialize_seq_product(0)?.end());
48
49// `u8` is implemented below as we wish to provide different `__serialize_array` impl (see below).
50impl_prim! {
51    (bool, serialize_bool)
52                       (u16, serialize_u16) (u32, serialize_u32) (u64, serialize_u64) (u128, serialize_u128) (u256, serialize_u256)
53    (i8, serialize_i8) (i16, serialize_i16) (i32, serialize_i32) (i64, serialize_i64) (i128, serialize_i128) (i256, serialize_i256)
54    (f32, serialize_f32) (f64, serialize_f64) (str, serialize_str)
55}
56
57// TODO(Centril): this special case doesn't seem well motivated.
58// Consider generalizing this to apply to all primitive types
59// so that we can move this into `impl_prim!`.
60// This will make BSATN-serializing `[u32]` faster for example.
61impl Serialize for u8 {
62    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
63        serializer.serialize_u8(*self)
64    }
65
66    fn __serialize_array<S: Serializer>(this: &[Self], serializer: S) -> Result<S::Ok, S::Error>
67    where
68        Self: Sized,
69    {
70        serializer.serialize_bytes(this)
71    }
72}
73
74impl_serialize!([] F32, (self, ser) => f32::from(*self).serialize(ser));
75impl_serialize!([] F64, (self, ser) => f64::from(*self).serialize(ser));
76impl_serialize!([T: Serialize] Vec<T>, (self, ser)  => (**self).serialize(ser));
77impl_serialize!([T: Serialize, const N: usize] SmallVec<[T; N]>, (self, ser)  => (**self).serialize(ser));
78impl_serialize!([T: Serialize] [T], (self, ser) => T::__serialize_array(self, ser));
79impl_serialize!([T: Serialize, const N: usize] [T; N], (self, ser) => T::__serialize_array(self, ser));
80impl_serialize!([T: Serialize + ?Sized] Box<T>, (self, ser) => (**self).serialize(ser));
81impl_serialize!([T: Serialize + ?Sized] Rc<T>, (self, ser) => (**self).serialize(ser));
82impl_serialize!([T: Serialize + ?Sized] Arc<T>, (self, ser) => (**self).serialize(ser));
83impl_serialize!([T: Serialize + ?Sized] &T, (self, ser) => (**self).serialize(ser));
84impl_serialize!([] String, (self, ser) => ser.serialize_str(self));
85impl_serialize!([T: Serialize] Option<T>, (self, ser) => match self {
86    Some(v) => ser.serialize_variant(0, Some("some"), v),
87    None => ser.serialize_variant(1, Some("none"), &()),
88});
89impl_serialize!([T: Serialize, E: Serialize] Result<T, E>, (self, ser) => match self {
90    Ok(v) => ser.serialize_variant(0, Some("ok"), v),
91    Err(e) => ser.serialize_variant(1, Some("err"), e),
92});
93impl_serialize!([T: Serialize] Bound<T>, (self, ser) => match self {
94    Bound::Included(x) => ser.serialize_variant(0, Some("included"), x),
95    Bound::Excluded(x) => ser.serialize_variant(1, Some("excluded"), x),
96    Bound::Unbounded => ser.serialize_variant(2, Some("unbounded"), &()),
97});
98impl_serialize!([] AlgebraicValue, (self, ser) => match self {
99    Self::Sum(sum) => sum.serialize(ser),
100    Self::Product(prod) => prod.serialize(ser),
101    Self::Array(arr) => arr.serialize(ser),
102    Self::Bool(v) => ser.serialize_bool(*v),
103    Self::I8(v) => ser.serialize_i8(*v),
104    Self::U8(v) => ser.serialize_u8(*v),
105    Self::I16(v) => ser.serialize_i16(*v),
106    Self::U16(v) => ser.serialize_u16(*v),
107    Self::I32(v) => ser.serialize_i32(*v),
108    Self::U32(v) => ser.serialize_u32(*v),
109    Self::I64(v) => ser.serialize_i64(*v),
110    Self::U64(v) => ser.serialize_u64(*v),
111    Self::I128(v) => ser.serialize_i128(v.0),
112    Self::U128(v) => ser.serialize_u128(v.0),
113    Self::I256(v) => ser.serialize_i256(**v),
114    Self::U256(v) => ser.serialize_u256(**v),
115    Self::F32(v) => ser.serialize_f32((*v).into()),
116    Self::F64(v) => ser.serialize_f64((*v).into()),
117    // Self::Bytes(v) => ser.serialize_bytes(v),
118    Self::String(v) => ser.serialize_str(v),
119    Self::Min | Self::Max => panic!("not defined for Min/Max"),
120});
121impl_serialize!([] ProductValue, (self, ser) => {
122    let mut tup = ser.serialize_seq_product(self.elements.len())?;
123    for elem in &*self.elements {
124        tup.serialize_element(elem)?;
125    }
126    tup.end()
127});
128impl_serialize!([] SumValue, (self, ser) => ser.serialize_variant(self.tag, None, &*self.value));
129impl_serialize!([] ArrayValue, (self, ser) => match self {
130    Self::Sum(v) => v.serialize(ser),
131    Self::Product(v) => v.serialize(ser),
132    Self::Bool(v) => v.serialize(ser),
133    Self::I8(v) => v.serialize(ser),
134    Self::U8(v) => v.serialize(ser),
135    Self::I16(v) => v.serialize(ser),
136    Self::U16(v) => v.serialize(ser),
137    Self::I32(v) => v.serialize(ser),
138    Self::U32(v) => v.serialize(ser),
139    Self::I64(v) => v.serialize(ser),
140    Self::U64(v) => v.serialize(ser),
141    Self::I128(v) => v.serialize(ser),
142    Self::U128(v) => v.serialize(ser),
143    Self::I256(v) => v.serialize(ser),
144    Self::U256(v) => v.serialize(ser),
145    Self::F32(v) => v.serialize(ser),
146    Self::F64(v) => v.serialize(ser),
147    Self::String(v) => v.serialize(ser),
148    Self::Array(v) => v.serialize(ser),
149});
150impl_serialize!([] ValueWithType<'_, AlgebraicValue>, (self, ser) => {
151    let mut ty = self.ty();
152    loop { // We're doing this because of `Ref`s.
153        break match (self.value(), ty) {
154            (_, &AlgebraicType::Ref(r)) => {
155                ty = &self.typespace()[r];
156                continue;
157            }
158            (AlgebraicValue::Sum(val), AlgebraicType::Sum(ty)) => self.with(ty, val).serialize(ser),
159            (AlgebraicValue::Product(val), AlgebraicType::Product(ty)) => self.with(ty, val).serialize(ser),
160            (AlgebraicValue::Array(val), AlgebraicType::Array(ty)) => self.with(ty, val).serialize(ser),
161            (AlgebraicValue::Bool(v), AlgebraicType::Bool) => ser.serialize_bool(*v),
162            (AlgebraicValue::I8(v), AlgebraicType::I8) => ser.serialize_i8(*v),
163            (AlgebraicValue::U8(v), AlgebraicType::U8) => ser.serialize_u8(*v),
164            (AlgebraicValue::I16(v), AlgebraicType::I16) => ser.serialize_i16(*v),
165            (AlgebraicValue::U16(v), AlgebraicType::U16) => ser.serialize_u16(*v),
166            (AlgebraicValue::I32(v), AlgebraicType::I32) => ser.serialize_i32(*v),
167            (AlgebraicValue::U32(v), AlgebraicType::U32) => ser.serialize_u32(*v),
168            (AlgebraicValue::I64(v), AlgebraicType::I64) => ser.serialize_i64(*v),
169            (AlgebraicValue::U64(v), AlgebraicType::U64) => ser.serialize_u64(*v),
170            (AlgebraicValue::I128(v), AlgebraicType::I128) => ser.serialize_i128(v.0),
171            (AlgebraicValue::U128(v), AlgebraicType::U128) => ser.serialize_u128(v.0),
172            (AlgebraicValue::I256(v), AlgebraicType::I256) => ser.serialize_i256(**v),
173            (AlgebraicValue::U256(v), AlgebraicType::U256) => ser.serialize_u256(**v),
174            (AlgebraicValue::F32(v), AlgebraicType::F32) => ser.serialize_f32((*v).into()),
175            (AlgebraicValue::F64(v), AlgebraicType::F64) => ser.serialize_f64((*v).into()),
176            (AlgebraicValue::String(s), AlgebraicType::String) => ser.serialize_str(s),
177            (val, ty) => panic!("mismatched value and schema : {val:?} {ty:?}"),
178        };
179    }
180});
181impl_serialize!(
182    [T: crate::Value] where [for<'a> ValueWithType<'a, T>: Serialize]
183    ValueWithType<'_, Box<[T]>>,
184    (self, ser) => {
185        let mut vec = ser.serialize_array(self.value().len())?;
186        for val in self.iter() {
187            vec.serialize_element(&val)?;
188        }
189        vec.end()
190    }
191);
192impl_serialize!([] ValueWithType<'_, SumValue>, (self, ser) => {
193    let sv = self.value();
194    let (tag, val) = (sv.tag, &*sv.value);
195    let var_ty = &self.ty().variants[tag as usize]; // Extract the variant type by tag.
196    ser.serialize_variant(tag, var_ty.name(), &self.with(&var_ty.algebraic_type, val))
197});
198impl_serialize!([] ValueWithType<'_, ProductValue>, (self, ser) => {
199    let val = &self.value().elements;
200    assert_eq!(val.len(), self.ty().elements.len());
201    let mut prod = ser.serialize_named_product(val.len())?;
202    for (val, el_ty) in val.iter().zip(&*self.ty().elements) {
203        prod.serialize_element(el_ty.name(), &self.with(&el_ty.algebraic_type, val))?
204    }
205    prod.end()
206});
207impl_serialize!([] ValueWithType<'_, ArrayValue>, (self, ser) => {
208    let mut ty = &*self.ty().elem_ty;
209    loop { // We're doing this because of `Ref`s.
210        break match (self.value(), ty) {
211            (_, &AlgebraicType::Ref(r)) => {
212                ty = &self.typespace()[r];
213                continue;
214            }
215            (ArrayValue::Sum(v), AlgebraicType::Sum(ty)) => self.with(ty, v).serialize(ser),
216            (ArrayValue::Product(v), AlgebraicType::Product(ty)) => self.with(ty, v).serialize(ser),
217            (ArrayValue::Bool(v), AlgebraicType::Bool) => v.serialize(ser),
218            (ArrayValue::I8(v), AlgebraicType::I8) => v.serialize(ser),
219            (ArrayValue::U8(v), AlgebraicType::U8) => v.serialize(ser),
220            (ArrayValue::I16(v), AlgebraicType::I16) => v.serialize(ser),
221            (ArrayValue::U16(v), AlgebraicType::U16) => v.serialize(ser),
222            (ArrayValue::I32(v), AlgebraicType::I32) => v.serialize(ser),
223            (ArrayValue::U32(v), AlgebraicType::U32) => v.serialize(ser),
224            (ArrayValue::I64(v), AlgebraicType::I64) => v.serialize(ser),
225            (ArrayValue::U64(v), AlgebraicType::U64) => v.serialize(ser),
226            (ArrayValue::I128(v), AlgebraicType::I128) => v.serialize(ser),
227            (ArrayValue::U128(v), AlgebraicType::U128) => v.serialize(ser),
228            (ArrayValue::I256(v), AlgebraicType::I256) => v.serialize(ser),
229            (ArrayValue::U256(v), AlgebraicType::U256) => v.serialize(ser),
230            (ArrayValue::F32(v), AlgebraicType::F32) => v.serialize(ser),
231            (ArrayValue::F64(v), AlgebraicType::F64) => v.serialize(ser),
232            (ArrayValue::String(v), AlgebraicType::String) => v.serialize(ser),
233            (ArrayValue::Array(v), AlgebraicType::Array(ty)) => self.with(ty, v).serialize(ser),
234            (val, _) if val.is_empty() => ser.serialize_array(0)?.end(),
235            (val, ty) => panic!("mismatched value and schema: {val:?} {ty:?}"),
236        }
237    }
238});
239
240impl_serialize!([] spacetimedb_primitives::TableId, (self, ser) => ser.serialize_u32(self.0));
241impl_serialize!([] spacetimedb_primitives::SequenceId, (self, ser) => ser.serialize_u32(self.0));
242impl_serialize!([] spacetimedb_primitives::IndexId, (self, ser) => ser.serialize_u32(self.0));
243impl_serialize!([] spacetimedb_primitives::ConstraintId, (self, ser) => ser.serialize_u32(self.0));
244impl_serialize!([] spacetimedb_primitives::ColId, (self, ser) => ser.serialize_u16(self.0));
245impl_serialize!([] spacetimedb_primitives::ScheduleId, (self, ser) => ser.serialize_u32(self.0));
246
247impl_serialize!([] ColList, (self, ser) => {
248    let mut arr = ser.serialize_array(self.len() as usize)?;
249       for x in self.iter() {
250           arr.serialize_element(&x)?;
251       }
252       arr.end()
253});
254impl_serialize!([] ColSet, (self, ser) => {
255    let list: &ColList = self;
256    list.serialize(ser)
257});
258
259#[cfg(feature = "blake3")]
260impl_serialize!([] blake3::Hash, (self, ser) => self.as_bytes().serialize(ser));
261
262impl_serialize!([] bytes::Bytes, (self, ser) => ser.serialize_bytes(self));
263
264#[cfg(feature = "bytestring")]
265impl_serialize!([] bytestring::ByteString, (self, ser) => ser.serialize_str(self));