spacetimedb_sats/ser/
impls.rs

1use super::{Serialize, SerializeArray, 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
47// All the tuple types:
48#[macro_export]
49macro_rules! count {
50    () => (0usize);
51    ( $x:tt $($xs:tt)* ) => (1usize + $crate::count!($($xs)*));
52}
53macro_rules! impl_serialize_tuple {
54    ($($ty_name:ident),*) => {
55        impl_serialize!([$($ty_name: Serialize),*] ($($ty_name,)*), (self, ser) => {
56            let mut _tup = ser.serialize_seq_product(count!($($ty_name)*))?;
57            #[allow(non_snake_case)]
58            let ($($ty_name,)*) = self;
59            $(_tup.serialize_element($ty_name)?;)*
60            _tup.end()
61        });
62    };
63}
64impl_serialize_tuple!();
65impl_serialize_tuple!(T0);
66impl_serialize_tuple!(T0, T1);
67impl_serialize_tuple!(T0, T1, T2);
68impl_serialize_tuple!(T0, T1, T2, T3);
69impl_serialize_tuple!(T0, T1, T2, T3, T4);
70impl_serialize_tuple!(T0, T1, T2, T3, T4, T5);
71impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6);
72impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6, T7);
73impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
74impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
75impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
76impl_serialize_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
77
78// `u8` is implemented below as we wish to provide different `__serialize_array` impl (see below).
79impl_prim! {
80    (bool, serialize_bool)
81                       (u16, serialize_u16) (u32, serialize_u32) (u64, serialize_u64) (u128, serialize_u128) (u256, serialize_u256)
82    (i8, serialize_i8) (i16, serialize_i16) (i32, serialize_i32) (i64, serialize_i64) (i128, serialize_i128) (i256, serialize_i256)
83    (f32, serialize_f32) (f64, serialize_f64) (str, serialize_str)
84}
85
86// TODO(Centril): this special case doesn't seem well motivated.
87// Consider generalizing this to apply to all primitive types
88// so that we can move this into `impl_prim!`.
89// This will make BSATN-serializing `[u32]` faster for example.
90impl Serialize for u8 {
91    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
92        serializer.serialize_u8(*self)
93    }
94
95    fn __serialize_array<S: Serializer>(this: &[Self], serializer: S) -> Result<S::Ok, S::Error>
96    where
97        Self: Sized,
98    {
99        serializer.serialize_bytes(this)
100    }
101}
102
103impl_serialize!([] F32, (self, ser) => f32::from(*self).serialize(ser));
104impl_serialize!([] F64, (self, ser) => f64::from(*self).serialize(ser));
105impl_serialize!([T: Serialize] Vec<T>, (self, ser)  => (**self).serialize(ser));
106impl_serialize!([T: Serialize, const N: usize] SmallVec<[T; N]>, (self, ser)  => (**self).serialize(ser));
107impl_serialize!([T: Serialize] [T], (self, ser) => T::__serialize_array(self, ser));
108impl_serialize!([T: Serialize, const N: usize] [T; N], (self, ser) => T::__serialize_array(self, ser));
109impl_serialize!([T: Serialize + ?Sized] Box<T>, (self, ser) => (**self).serialize(ser));
110impl_serialize!([T: Serialize + ?Sized] Rc<T>, (self, ser) => (**self).serialize(ser));
111impl_serialize!([T: Serialize + ?Sized] Arc<T>, (self, ser) => (**self).serialize(ser));
112impl_serialize!([T: Serialize + ?Sized] &T, (self, ser) => (**self).serialize(ser));
113impl_serialize!([] String, (self, ser) => ser.serialize_str(self));
114impl_serialize!([T: Serialize] Option<T>, (self, ser) => match self {
115    Some(v) => ser.serialize_variant(0, Some("some"), v),
116    None => ser.serialize_variant(1, Some("none"), &()),
117});
118impl_serialize!([T: Serialize, E: Serialize] Result<T, E>, (self, ser) => match self {
119    Ok(v) => ser.serialize_variant(0, Some("ok"), v),
120    Err(e) => ser.serialize_variant(1, Some("err"), e),
121});
122impl_serialize!([T: Serialize] Bound<T>, (self, ser) => match self {
123    Bound::Included(x) => ser.serialize_variant(0, Some("included"), x),
124    Bound::Excluded(x) => ser.serialize_variant(1, Some("excluded"), x),
125    Bound::Unbounded => ser.serialize_variant(2, Some("unbounded"), &()),
126});
127impl_serialize!([] AlgebraicValue, (self, ser) => match self {
128    Self::Sum(sum) => sum.serialize(ser),
129    Self::Product(prod) => prod.serialize(ser),
130    Self::Array(arr) => arr.serialize(ser),
131    Self::Bool(v) => ser.serialize_bool(*v),
132    Self::I8(v) => ser.serialize_i8(*v),
133    Self::U8(v) => ser.serialize_u8(*v),
134    Self::I16(v) => ser.serialize_i16(*v),
135    Self::U16(v) => ser.serialize_u16(*v),
136    Self::I32(v) => ser.serialize_i32(*v),
137    Self::U32(v) => ser.serialize_u32(*v),
138    Self::I64(v) => ser.serialize_i64(*v),
139    Self::U64(v) => ser.serialize_u64(*v),
140    Self::I128(v) => ser.serialize_i128(v.0),
141    Self::U128(v) => ser.serialize_u128(v.0),
142    Self::I256(v) => ser.serialize_i256(**v),
143    Self::U256(v) => ser.serialize_u256(**v),
144    Self::F32(v) => ser.serialize_f32((*v).into()),
145    Self::F64(v) => ser.serialize_f64((*v).into()),
146    // Self::Bytes(v) => ser.serialize_bytes(v),
147    Self::String(v) => ser.serialize_str(v),
148    Self::Min | Self::Max => panic!("not defined for Min/Max"),
149});
150impl_serialize!([] ProductValue, (self, ser) => {
151    let mut tup = ser.serialize_seq_product(self.elements.len())?;
152    for elem in &*self.elements {
153        tup.serialize_element(elem)?;
154    }
155    tup.end()
156});
157impl_serialize!([] SumValue, (self, ser) => ser.serialize_variant(self.tag, None, &*self.value));
158impl_serialize!([] ArrayValue, (self, ser) => match self {
159    Self::Sum(v) => v.serialize(ser),
160    Self::Product(v) => v.serialize(ser),
161    Self::Bool(v) => v.serialize(ser),
162    Self::I8(v) => v.serialize(ser),
163    Self::U8(v) => v.serialize(ser),
164    Self::I16(v) => v.serialize(ser),
165    Self::U16(v) => v.serialize(ser),
166    Self::I32(v) => v.serialize(ser),
167    Self::U32(v) => v.serialize(ser),
168    Self::I64(v) => v.serialize(ser),
169    Self::U64(v) => v.serialize(ser),
170    Self::I128(v) => v.serialize(ser),
171    Self::U128(v) => v.serialize(ser),
172    Self::I256(v) => v.serialize(ser),
173    Self::U256(v) => v.serialize(ser),
174    Self::F32(v) => v.serialize(ser),
175    Self::F64(v) => v.serialize(ser),
176    Self::String(v) => v.serialize(ser),
177    Self::Array(v) => v.serialize(ser),
178});
179impl_serialize!([] ValueWithType<'_, AlgebraicValue>, (self, ser) => {
180    let mut ty = self.ty();
181    loop { // We're doing this because of `Ref`s.
182        break match (self.value(), ty) {
183            (_, &AlgebraicType::Ref(r)) => {
184                ty = &self.typespace()[r];
185                continue;
186            }
187            (AlgebraicValue::Sum(val), AlgebraicType::Sum(ty)) => self.with(ty, val).serialize(ser),
188            (AlgebraicValue::Product(val), AlgebraicType::Product(ty)) => self.with(ty, val).serialize(ser),
189            (AlgebraicValue::Array(val), AlgebraicType::Array(ty)) => self.with(ty, val).serialize(ser),
190            (AlgebraicValue::Bool(v), AlgebraicType::Bool) => ser.serialize_bool(*v),
191            (AlgebraicValue::I8(v), AlgebraicType::I8) => ser.serialize_i8(*v),
192            (AlgebraicValue::U8(v), AlgebraicType::U8) => ser.serialize_u8(*v),
193            (AlgebraicValue::I16(v), AlgebraicType::I16) => ser.serialize_i16(*v),
194            (AlgebraicValue::U16(v), AlgebraicType::U16) => ser.serialize_u16(*v),
195            (AlgebraicValue::I32(v), AlgebraicType::I32) => ser.serialize_i32(*v),
196            (AlgebraicValue::U32(v), AlgebraicType::U32) => ser.serialize_u32(*v),
197            (AlgebraicValue::I64(v), AlgebraicType::I64) => ser.serialize_i64(*v),
198            (AlgebraicValue::U64(v), AlgebraicType::U64) => ser.serialize_u64(*v),
199            (AlgebraicValue::I128(v), AlgebraicType::I128) => ser.serialize_i128(v.0),
200            (AlgebraicValue::U128(v), AlgebraicType::U128) => ser.serialize_u128(v.0),
201            (AlgebraicValue::I256(v), AlgebraicType::I256) => ser.serialize_i256(**v),
202            (AlgebraicValue::U256(v), AlgebraicType::U256) => ser.serialize_u256(**v),
203            (AlgebraicValue::F32(v), AlgebraicType::F32) => ser.serialize_f32((*v).into()),
204            (AlgebraicValue::F64(v), AlgebraicType::F64) => ser.serialize_f64((*v).into()),
205            (AlgebraicValue::String(s), AlgebraicType::String) => ser.serialize_str(s),
206            (val, ty) => panic!("mismatched value and schema : {val:?} {ty:?}"),
207        };
208    }
209});
210impl_serialize!(
211    [T: crate::Value] where [for<'a> ValueWithType<'a, T>: Serialize]
212    ValueWithType<'_, Box<[T]>>,
213    (self, ser) => {
214        let mut vec = ser.serialize_array(self.value().len())?;
215        for val in self.iter() {
216            vec.serialize_element(&val)?;
217        }
218        vec.end()
219    }
220);
221impl_serialize!([] ValueWithType<'_, SumValue>, (self, ser) => {
222   ser.serialize_variant_raw(self)
223});
224impl_serialize!([] ValueWithType<'_, ProductValue>, (self, ser) => {
225    ser.serialize_named_product_raw(self)
226});
227impl_serialize!([] ValueWithType<'_, ArrayValue>, (self, ser) => {
228    let mut ty = &*self.ty().elem_ty;
229    loop { // We're doing this because of `Ref`s.
230        break match (self.value(), ty) {
231            (_, &AlgebraicType::Ref(r)) => {
232                ty = &self.typespace()[r];
233                continue;
234            }
235            (ArrayValue::Sum(v), AlgebraicType::Sum(ty)) => self.with(ty, v).serialize(ser),
236            (ArrayValue::Product(v), AlgebraicType::Product(ty)) => self.with(ty, v).serialize(ser),
237            (ArrayValue::Bool(v), AlgebraicType::Bool) => v.serialize(ser),
238            (ArrayValue::I8(v), AlgebraicType::I8) => v.serialize(ser),
239            (ArrayValue::U8(v), AlgebraicType::U8) => v.serialize(ser),
240            (ArrayValue::I16(v), AlgebraicType::I16) => v.serialize(ser),
241            (ArrayValue::U16(v), AlgebraicType::U16) => v.serialize(ser),
242            (ArrayValue::I32(v), AlgebraicType::I32) => v.serialize(ser),
243            (ArrayValue::U32(v), AlgebraicType::U32) => v.serialize(ser),
244            (ArrayValue::I64(v), AlgebraicType::I64) => v.serialize(ser),
245            (ArrayValue::U64(v), AlgebraicType::U64) => v.serialize(ser),
246            (ArrayValue::I128(v), AlgebraicType::I128) => v.serialize(ser),
247            (ArrayValue::U128(v), AlgebraicType::U128) => v.serialize(ser),
248            (ArrayValue::I256(v), AlgebraicType::I256) => v.serialize(ser),
249            (ArrayValue::U256(v), AlgebraicType::U256) => v.serialize(ser),
250            (ArrayValue::F32(v), AlgebraicType::F32) => v.serialize(ser),
251            (ArrayValue::F64(v), AlgebraicType::F64) => v.serialize(ser),
252            (ArrayValue::String(v), AlgebraicType::String) => v.serialize(ser),
253            (ArrayValue::Array(v), AlgebraicType::Array(ty)) => self.with(ty, v).serialize(ser),
254            (val, _) if val.is_empty() => ser.serialize_array(0)?.end(),
255            (val, ty) => panic!("mismatched value and schema: {val:?} {ty:?}"),
256        }
257    }
258});
259
260impl_serialize!([] spacetimedb_primitives::TableId, (self, ser) => ser.serialize_u32(self.0));
261impl_serialize!([] spacetimedb_primitives::SequenceId, (self, ser) => ser.serialize_u32(self.0));
262impl_serialize!([] spacetimedb_primitives::IndexId, (self, ser) => ser.serialize_u32(self.0));
263impl_serialize!([] spacetimedb_primitives::ConstraintId, (self, ser) => ser.serialize_u32(self.0));
264impl_serialize!([] spacetimedb_primitives::ColId, (self, ser) => ser.serialize_u16(self.0));
265impl_serialize!([] spacetimedb_primitives::ScheduleId, (self, ser) => ser.serialize_u32(self.0));
266
267impl_serialize!([] ColList, (self, ser) => {
268    let mut arr = ser.serialize_array(self.len() as usize)?;
269       for x in self.iter() {
270           arr.serialize_element(&x)?;
271       }
272       arr.end()
273});
274impl_serialize!([] ColSet, (self, ser) => {
275    let list: &ColList = self;
276    list.serialize(ser)
277});
278
279#[cfg(feature = "blake3")]
280impl_serialize!([] blake3::Hash, (self, ser) => self.as_bytes().serialize(ser));
281
282impl_serialize!([] bytes::Bytes, (self, ser) => ser.serialize_bytes(self));
283
284#[cfg(feature = "bytestring")]
285impl_serialize!([] bytestring::ByteString, (self, ser) => ser.serialize_str(self));