spacetimedb_sats/de/
impls.rs

1use super::{
2    BasicSmallVecVisitor, BasicVecVisitor, Deserialize, DeserializeSeed, Deserializer, Error, FieldNameVisitor,
3    ProductKind, ProductVisitor, SeqProductAccess, SliceVisitor, SumAccess, SumVisitor, VariantAccess, VariantVisitor,
4};
5use crate::{
6    de::{array_visit, ArrayAccess, ArrayVisitor, GrowingVec},
7    AlgebraicType, AlgebraicValue, ArrayType, ArrayValue, ProductType, ProductTypeElement, ProductValue, SumType,
8    SumValue, WithTypespace, F32, F64,
9};
10use crate::{i256, u256};
11use core::{iter, marker::PhantomData, ops::Bound};
12use smallvec::SmallVec;
13use spacetimedb_primitives::{ColId, ColList};
14use std::{borrow::Cow, rc::Rc, sync::Arc};
15
16/// Implements [`Deserialize`] for a type in a simplified manner.
17///
18/// An example:
19/// ```ignore
20/// impl_deserialize!(
21/// //     Type parameters  Optional where  Impl type
22/// //            v               v             v
23/// //   ----------------  --------------- ----------
24///     [T: Deserialize<'de>] where [T: Copy] std::rc::Rc<T>,
25/// //  The `deserialize` implementation where `de` is the `Deserializer<'de>`
26/// //  and the expression right of `=>` is the body of `deserialize`.
27///     de => T::deserialize(de).map(std::rc::Rc::new)
28/// );
29/// ```
30#[macro_export]
31macro_rules! impl_deserialize {
32    ([$($generics:tt)*] $(where [$($wc:tt)*])? $typ:ty, $de:ident => $body:expr) => {
33        impl<'de, $($generics)*> $crate::de::Deserialize<'de> for $typ {
34            fn deserialize<D: $crate::de::Deserializer<'de>>($de: D) -> Result<Self, D::Error> { $body }
35        }
36    };
37}
38
39/// Implements [`Deserialize`] for a primitive type.
40///
41/// The `$method` is a parameterless method on `deserializer` to call.
42macro_rules! impl_prim {
43    ($(($prim:ty, $method:ident))*) => {
44        $(impl_deserialize!([] $prim, de => de.$method());)*
45    };
46}
47
48impl_prim! {
49    (bool, deserialize_bool)
50    /*(u8, deserialize_u8)*/ (u16, deserialize_u16) (u32, deserialize_u32) (u64, deserialize_u64) (u128, deserialize_u128) (u256, deserialize_u256)
51    (i8, deserialize_i8)     (i16, deserialize_i16) (i32, deserialize_i32) (i64, deserialize_i64) (i128, deserialize_i128) (i256, deserialize_i256)
52    (f32, deserialize_f32) (f64, deserialize_f64)
53}
54
55struct TupleVisitor<A>(PhantomData<A>);
56#[derive(Copy, Clone)]
57struct TupleNameVisitorMax(usize);
58
59impl FieldNameVisitor<'_> for TupleNameVisitorMax {
60    // The index of the field name.
61    type Output = usize;
62
63    fn field_names(&self) -> impl '_ + Iterator<Item = Option<&str>> {
64        iter::repeat_n(None, self.0)
65    }
66
67    fn kind(&self) -> ProductKind {
68        ProductKind::Normal
69    }
70
71    fn visit<E: Error>(self, name: &str) -> Result<Self::Output, E> {
72        let err = || Error::unknown_field_name(name, &self);
73        // Convert `name` to an index.
74        let Ok(index) = name.parse() else {
75            return Err(err());
76        };
77        // Confirm that the index exists or error.
78        if index < self.0 {
79            Ok(index)
80        } else {
81            Err(err())
82        }
83    }
84
85    fn visit_seq(self, index: usize) -> Self::Output {
86        // Assert that the index exists.
87        assert!(index < self.0);
88        index
89    }
90}
91
92macro_rules! impl_deserialize_tuple {
93    ($($ty_name:ident => $const_val:literal),*) => {
94        impl<'de, $($ty_name: Deserialize<'de>),*> ProductVisitor<'de> for TupleVisitor<($($ty_name,)*)> {
95            type Output = ($($ty_name,)*);
96            fn product_name(&self) -> Option<&str> { None }
97            fn product_len(&self) -> usize { crate::count!($($ty_name)*) }
98            fn visit_seq_product<A: SeqProductAccess<'de>>(self, mut _prod: A) -> Result<Self::Output, A::Error> {
99                $(
100                    #[allow(non_snake_case)]
101                    let $ty_name = _prod
102                        .next_element()?
103                        .ok_or_else(|| Error::invalid_product_length($const_val, &self))?;
104                )*
105
106                Ok(($($ty_name,)*))
107            }
108            fn visit_named_product<A: super::NamedProductAccess<'de>>(self, mut prod: A) -> Result<Self::Output, A::Error> {
109                $(
110                    #[allow(non_snake_case)]
111                    let mut $ty_name = None;
112                )*
113
114                let visit = TupleNameVisitorMax(self.product_len());
115                while let Some(index) = prod.get_field_ident(visit)? {
116                    match index {
117                        $($const_val => {
118                            if $ty_name.is_some() {
119                                return Err(A::Error::duplicate_field($const_val, None, &self))
120                            }
121                            $ty_name = Some(prod.get_field_value()?);
122                        })*
123                        index => return Err(Error::invalid_product_length(index, &self)),
124                    }
125                }
126                Ok(($(
127                    $ty_name.ok_or_else(|| A::Error::missing_field($const_val, None, &self))?,
128                )*))
129            }
130        }
131
132        impl_deserialize!([$($ty_name: Deserialize<'de>),*] ($($ty_name,)*), de => {
133            de.deserialize_product(TupleVisitor::<($($ty_name,)*)>(PhantomData))
134        });
135    };
136}
137
138impl_deserialize_tuple!();
139impl_deserialize_tuple!(T0 => 0);
140impl_deserialize_tuple!(T0 => 0, T1 => 1);
141impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2);
142impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3);
143impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4);
144impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5);
145impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6);
146impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6, T7 => 7);
147impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6, T7 => 7, T8 => 8);
148impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6, T7 => 7, T8 => 8, T9 => 9);
149impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6, T7 => 7, T8 => 8, T9 => 9, T10 => 10);
150impl_deserialize_tuple!(T0 => 0, T1 => 1, T2 => 2, T3 => 3, T4 => 4, T5 => 5, T6 => 6, T7 => 7, T8 => 8, T9 => 9, T10 => 10, T11 => 11);
151
152impl<'de> Deserialize<'de> for u8 {
153    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
154        deserializer.deserialize_u8()
155    }
156
157    // Specialize `Vec<u8>` deserialization.
158    // This is more likely to compile down to a `memcpy`.
159    fn __deserialize_vec<D: Deserializer<'de>>(deserializer: D) -> Result<Vec<Self>, D::Error> {
160        deserializer.deserialize_bytes(OwnedSliceVisitor)
161    }
162
163    fn __deserialize_array<D: Deserializer<'de>, const N: usize>(deserializer: D) -> Result<[Self; N], D::Error> {
164        deserializer.deserialize_bytes(ByteArrayVisitor)
165    }
166}
167
168impl_deserialize!([] F32, de => f32::deserialize(de).map(Into::into));
169impl_deserialize!([] F64, de => f64::deserialize(de).map(Into::into));
170impl_deserialize!([] String, de => de.deserialize_str(OwnedSliceVisitor));
171impl_deserialize!([T: Deserialize<'de>] Vec<T>, de => T::__deserialize_vec(de));
172impl_deserialize!([T: Deserialize<'de>, const N: usize] SmallVec<[T; N]>, de => {
173    de.deserialize_array(BasicSmallVecVisitor)
174});
175impl_deserialize!([T: Deserialize<'de>, const N: usize] [T; N], de => T::__deserialize_array(de));
176impl_deserialize!([] Box<str>, de => String::deserialize(de).map(|s| s.into_boxed_str()));
177impl_deserialize!([T: Deserialize<'de>] Box<[T]>, de => Vec::deserialize(de).map(|s| s.into_boxed_slice()));
178impl_deserialize!([T: Deserialize<'de>] Rc<[T]>, de => Vec::deserialize(de).map(|s| s.into()));
179impl_deserialize!([T: Deserialize<'de>] Arc<[T]>, de => Vec::deserialize(de).map(|s| s.into()));
180
181/// The visitor converts the slice to its owned version.
182struct OwnedSliceVisitor;
183
184impl<T: ToOwned + ?Sized> SliceVisitor<'_, T> for OwnedSliceVisitor {
185    type Output = T::Owned;
186
187    fn visit<E: Error>(self, slice: &T) -> Result<Self::Output, E> {
188        Ok(slice.to_owned())
189    }
190
191    fn visit_owned<E: Error>(self, buf: T::Owned) -> Result<Self::Output, E> {
192        Ok(buf)
193    }
194}
195
196/// The visitor will convert the byte slice to `[u8; N]`.
197///
198/// When `slice.len() != N` an error will be raised.
199struct ByteArrayVisitor<const N: usize>;
200
201impl<const N: usize> SliceVisitor<'_, [u8]> for ByteArrayVisitor<N> {
202    type Output = [u8; N];
203
204    fn visit<E: Error>(self, slice: &[u8]) -> Result<Self::Output, E> {
205        slice.try_into().map_err(|_| {
206            Error::custom(if slice.len() > N {
207                "too many elements for array"
208            } else {
209                "too few elements for array"
210            })
211        })
212    }
213}
214
215impl_deserialize!([] &'de str, de => de.deserialize_str(BorrowedSliceVisitor));
216impl_deserialize!([] &'de [u8], de => de.deserialize_bytes(BorrowedSliceVisitor));
217
218/// The visitor returns the slice as-is and borrowed.
219pub(crate) struct BorrowedSliceVisitor;
220
221impl<'de, T: ToOwned + ?Sized + 'de> SliceVisitor<'de, T> for BorrowedSliceVisitor {
222    type Output = &'de T;
223
224    fn visit<E: Error>(self, _: &T) -> Result<Self::Output, E> {
225        Err(E::custom("expected *borrowed* slice"))
226    }
227
228    fn visit_borrowed<E: Error>(self, borrowed_slice: &'de T) -> Result<Self::Output, E> {
229        Ok(borrowed_slice)
230    }
231}
232
233impl_deserialize!([] Cow<'de, str>, de => de.deserialize_str(CowSliceVisitor));
234impl_deserialize!([] Cow<'de, [u8]>, de => de.deserialize_bytes(CowSliceVisitor));
235
236/// The visitor works with either owned or borrowed versions to produce `Cow<'de, T>`.
237struct CowSliceVisitor;
238
239impl<'de, T: ToOwned + ?Sized + 'de> SliceVisitor<'de, T> for CowSliceVisitor {
240    type Output = Cow<'de, T>;
241
242    fn visit<E: Error>(self, slice: &T) -> Result<Self::Output, E> {
243        self.visit_owned(slice.to_owned())
244    }
245
246    fn visit_owned<E: Error>(self, buf: <T as ToOwned>::Owned) -> Result<Self::Output, E> {
247        Ok(Cow::Owned(buf))
248    }
249
250    fn visit_borrowed<E: Error>(self, borrowed_slice: &'de T) -> Result<Self::Output, E> {
251        Ok(Cow::Borrowed(borrowed_slice))
252    }
253}
254
255impl_deserialize!([T: Deserialize<'de>] Box<T>, de => T::deserialize(de).map(Box::new));
256impl_deserialize!([T: Deserialize<'de>] Option<T>, de => de.deserialize_sum(OptionVisitor(PhantomData)));
257
258/// The visitor deserializes an `Option<T>`.
259struct OptionVisitor<T>(PhantomData<T>);
260
261impl<'de, T: Deserialize<'de>> SumVisitor<'de> for OptionVisitor<T> {
262    type Output = Option<T>;
263
264    fn sum_name(&self) -> Option<&str> {
265        Some("option")
266    }
267
268    fn is_option(&self) -> bool {
269        true
270    }
271
272    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
273        // Determine the variant.
274        let (some, data) = data.variant(self)?;
275
276        // Deserialize contents for it.
277        Ok(if some {
278            Some(data.deserialize()?)
279        } else {
280            data.deserialize::<()>()?;
281            None
282        })
283    }
284}
285
286impl<'de, T: Deserialize<'de>> VariantVisitor<'de> for OptionVisitor<T> {
287    type Output = bool;
288
289    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
290        ["some", "none"].into_iter()
291    }
292
293    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
294        match tag {
295            0 => Ok(true),
296            1 => Ok(false),
297            _ => Err(E::unknown_variant_tag(tag, &self)),
298        }
299    }
300
301    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
302        match name {
303            "some" => Ok(true),
304            "none" => Ok(false),
305            _ => Err(E::unknown_variant_name(name, &self)),
306        }
307    }
308}
309
310impl_deserialize!([T: Deserialize<'de>, E: Deserialize<'de>] Result<T, E>, de =>
311    de.deserialize_sum(ResultVisitor(PhantomData))
312);
313
314/// Visitor to deserialize a `Result<T, E>`.
315struct ResultVisitor<T, E>(PhantomData<(T, E)>);
316
317/// Variant determined by the [`VariantVisitor`] for `Result<T, E>`.
318enum ResultVariant {
319    Ok,
320    Err,
321}
322
323impl<'de, T: Deserialize<'de>, E: Deserialize<'de>> SumVisitor<'de> for ResultVisitor<T, E> {
324    type Output = Result<T, E>;
325
326    fn sum_name(&self) -> Option<&str> {
327        Some("result")
328    }
329
330    fn is_option(&self) -> bool {
331        false
332    }
333
334    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
335        let (variant, data) = data.variant(self)?;
336        Ok(match variant {
337            ResultVariant::Ok => Ok(data.deserialize()?),
338            ResultVariant::Err => Err(data.deserialize()?),
339        })
340    }
341}
342
343impl<'de, T: Deserialize<'de>, U: Deserialize<'de>> VariantVisitor<'de> for ResultVisitor<T, U> {
344    type Output = ResultVariant;
345
346    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
347        ["ok", "err"].into_iter()
348    }
349
350    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
351        match tag {
352            0 => Ok(ResultVariant::Ok),
353            1 => Ok(ResultVariant::Err),
354            _ => Err(E::unknown_variant_tag(tag, &self)),
355        }
356    }
357
358    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
359        match name {
360            "ok" => Ok(ResultVariant::Ok),
361            "err" => Ok(ResultVariant::Err),
362            _ => Err(E::unknown_variant_name(name, &self)),
363        }
364    }
365}
366
367/// The visitor deserializes a `Bound<T>`.
368#[derive(Clone, Copy)]
369pub struct WithBound<S>(pub S);
370
371impl<'de, S: Copy + DeserializeSeed<'de>> DeserializeSeed<'de> for WithBound<S> {
372    type Output = Bound<S::Output>;
373
374    fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Self::Output, D::Error> {
375        de.deserialize_sum(BoundVisitor(self.0))
376    }
377}
378
379/// The visitor deserializes a `Bound<T>`.
380struct BoundVisitor<S>(S);
381
382/// Variant determined by the [`BoundVisitor`] for `Bound<T>`.
383enum BoundVariant {
384    Included,
385    Excluded,
386    Unbounded,
387}
388
389impl<'de, S: Copy + DeserializeSeed<'de>> SumVisitor<'de> for BoundVisitor<S> {
390    type Output = Bound<S::Output>;
391
392    fn sum_name(&self) -> Option<&str> {
393        Some("bound")
394    }
395
396    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
397        // Determine the variant.
398        let this = self.0;
399        let (variant, data) = data.variant(self)?;
400
401        // Deserialize contents for it.
402        match variant {
403            BoundVariant::Included => data.deserialize_seed(this).map(Bound::Included),
404            BoundVariant::Excluded => data.deserialize_seed(this).map(Bound::Excluded),
405            BoundVariant::Unbounded => data.deserialize::<()>().map(|_| Bound::Unbounded),
406        }
407    }
408}
409
410impl<'de, T: Copy + DeserializeSeed<'de>> VariantVisitor<'de> for BoundVisitor<T> {
411    type Output = BoundVariant;
412
413    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
414        ["included", "excluded", "unbounded"].into_iter()
415    }
416
417    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
418        match tag {
419            0 => Ok(BoundVariant::Included),
420            1 => Ok(BoundVariant::Excluded),
421            // if this ever changes, edit crates/bindings/src/table.rs
422            2 => Ok(BoundVariant::Unbounded),
423            _ => Err(E::unknown_variant_tag(tag, &self)),
424        }
425    }
426
427    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
428        match name {
429            "included" => Ok(BoundVariant::Included),
430            "excluded" => Ok(BoundVariant::Excluded),
431            "unbounded" => Ok(BoundVariant::Unbounded),
432            _ => Err(E::unknown_variant_name(name, &self)),
433        }
434    }
435}
436
437impl<'de> DeserializeSeed<'de> for WithTypespace<'_, AlgebraicType> {
438    type Output = AlgebraicValue;
439
440    fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Self::Output, D::Error> {
441        match self.ty() {
442            AlgebraicType::Ref(r) => self.resolve(*r).deserialize(de),
443            AlgebraicType::Sum(sum) => self.with(sum).deserialize(de).map(Into::into),
444            AlgebraicType::Product(prod) => self.with(prod).deserialize(de).map(Into::into),
445            AlgebraicType::Array(ty) => self.with(ty).deserialize(de).map(Into::into),
446            AlgebraicType::Bool => bool::deserialize(de).map(Into::into),
447            AlgebraicType::I8 => i8::deserialize(de).map(Into::into),
448            AlgebraicType::U8 => u8::deserialize(de).map(Into::into),
449            AlgebraicType::I16 => i16::deserialize(de).map(Into::into),
450            AlgebraicType::U16 => u16::deserialize(de).map(Into::into),
451            AlgebraicType::I32 => i32::deserialize(de).map(Into::into),
452            AlgebraicType::U32 => u32::deserialize(de).map(Into::into),
453            AlgebraicType::I64 => i64::deserialize(de).map(Into::into),
454            AlgebraicType::U64 => u64::deserialize(de).map(Into::into),
455            AlgebraicType::I128 => i128::deserialize(de).map(Into::into),
456            AlgebraicType::U128 => u128::deserialize(de).map(Into::into),
457            AlgebraicType::I256 => i256::deserialize(de).map(Into::into),
458            AlgebraicType::U256 => u256::deserialize(de).map(Into::into),
459            AlgebraicType::F32 => f32::deserialize(de).map(Into::into),
460            AlgebraicType::F64 => f64::deserialize(de).map(Into::into),
461            AlgebraicType::String => <Box<str>>::deserialize(de).map(Into::into),
462        }
463    }
464}
465
466impl<'de> DeserializeSeed<'de> for WithTypespace<'_, SumType> {
467    type Output = SumValue;
468
469    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
470        deserializer.deserialize_sum(self)
471    }
472}
473
474impl<'de> SumVisitor<'de> for WithTypespace<'_, SumType> {
475    type Output = SumValue;
476
477    fn sum_name(&self) -> Option<&str> {
478        None
479    }
480
481    fn is_option(&self) -> bool {
482        self.ty().as_option().is_some()
483    }
484
485    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
486        let (tag, data) = data.variant(self)?;
487        // Find the variant type by `tag`.
488        let variant_ty = self.map(|ty| &ty.variants[tag as usize].algebraic_type);
489
490        let value = Box::new(data.deserialize_seed(variant_ty)?);
491        Ok(SumValue { tag, value })
492    }
493}
494
495impl VariantVisitor<'_> for WithTypespace<'_, SumType> {
496    type Output = u8;
497
498    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
499        // Provide the names known from the `SumType`.
500        self.ty().variants.iter().filter_map(|v| v.name())
501    }
502
503    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
504        // Verify that tag identifies a valid variant in `SumType`.
505        self.ty()
506            .variants
507            .get(tag as usize)
508            .ok_or_else(|| E::unknown_variant_tag(tag, &self))?;
509
510        Ok(tag)
511    }
512
513    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
514        // Translate the variant `name` to its tag.
515        self.ty()
516            .variants
517            .iter()
518            .position(|var| var.has_name(name))
519            .map(|pos| pos as u8)
520            .ok_or_else(|| E::unknown_variant_name(name, &self))
521    }
522}
523
524impl<'de> DeserializeSeed<'de> for WithTypespace<'_, ProductType> {
525    type Output = ProductValue;
526
527    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
528        deserializer.deserialize_product(self.map(|pt| &*pt.elements))
529    }
530}
531
532impl<'de> DeserializeSeed<'de> for WithTypespace<'_, [ProductTypeElement]> {
533    type Output = ProductValue;
534
535    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
536        deserializer.deserialize_product(self)
537    }
538}
539
540impl<'de> ProductVisitor<'de> for WithTypespace<'_, [ProductTypeElement]> {
541    type Output = ProductValue;
542
543    fn product_name(&self) -> Option<&str> {
544        None
545    }
546    fn product_len(&self) -> usize {
547        self.ty().len()
548    }
549
550    fn visit_seq_product<A: SeqProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
551        visit_seq_product(self, &self, tup)
552    }
553
554    fn visit_named_product<A: super::NamedProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
555        visit_named_product(self, &self, tup)
556    }
557}
558
559impl<'de> DeserializeSeed<'de> for WithTypespace<'_, ArrayType> {
560    type Output = ArrayValue;
561
562    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
563        /// Deserialize a vector and `map` it to the appropriate `ArrayValue` variant.
564        fn de_array<'de, D: Deserializer<'de>, T: Deserialize<'de>>(
565            de: D,
566            map: impl FnOnce(Box<[T]>) -> ArrayValue,
567        ) -> Result<ArrayValue, D::Error> {
568            de.deserialize_array(BasicVecVisitor).map(<Box<[_]>>::from).map(map)
569        }
570
571        let mut ty = &*self.ty().elem_ty;
572
573        // Loop, resolving `Ref`s, until we reach a non-`Ref` type.
574        loop {
575            break match ty {
576                AlgebraicType::Ref(r) => {
577                    // The only arm that will loop.
578                    ty = self.resolve(*r).ty();
579                    continue;
580                }
581                AlgebraicType::Sum(ty) => deserializer
582                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
583                    .map(<Box<[_]>>::from)
584                    .map(ArrayValue::Sum),
585                AlgebraicType::Product(ty) => deserializer
586                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
587                    .map(<Box<[_]>>::from)
588                    .map(ArrayValue::Product),
589                AlgebraicType::Array(ty) => deserializer
590                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
591                    .map(<Box<[_]>>::from)
592                    .map(ArrayValue::Array),
593                &AlgebraicType::Bool => de_array(deserializer, ArrayValue::Bool),
594                &AlgebraicType::I8 => de_array(deserializer, ArrayValue::I8),
595                &AlgebraicType::U8 => deserializer
596                    .deserialize_bytes(OwnedSliceVisitor)
597                    .map(<Box<[_]>>::from)
598                    .map(ArrayValue::U8),
599                &AlgebraicType::I16 => de_array(deserializer, ArrayValue::I16),
600                &AlgebraicType::U16 => de_array(deserializer, ArrayValue::U16),
601                &AlgebraicType::I32 => de_array(deserializer, ArrayValue::I32),
602                &AlgebraicType::U32 => de_array(deserializer, ArrayValue::U32),
603                &AlgebraicType::I64 => de_array(deserializer, ArrayValue::I64),
604                &AlgebraicType::U64 => de_array(deserializer, ArrayValue::U64),
605                &AlgebraicType::I128 => de_array(deserializer, ArrayValue::I128),
606                &AlgebraicType::U128 => de_array(deserializer, ArrayValue::U128),
607                &AlgebraicType::I256 => de_array(deserializer, ArrayValue::I256),
608                &AlgebraicType::U256 => de_array(deserializer, ArrayValue::U256),
609                &AlgebraicType::F32 => de_array(deserializer, ArrayValue::F32),
610                &AlgebraicType::F64 => de_array(deserializer, ArrayValue::F64),
611                &AlgebraicType::String => de_array(deserializer, ArrayValue::String),
612            };
613        }
614    }
615}
616
617// impl<'de> DeserializeSeed<'de> for &ReducerDef {
618//     type Output = ProductValue;
619
620//     fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
621//         deserializer.deserialize_product(self)
622//     }
623// }
624
625// impl<'de> ProductVisitor<'de> for &ReducerDef {
626//     type Output = ProductValue;
627
628//     fn product_name(&self) -> Option<&str> {
629//         self.name.as_deref()
630//     }
631//     fn product_len(&self) -> usize {
632//         self.args.len()
633//     }
634//     fn product_kind(&self) -> ProductKind {
635//         ProductKind::ReducerArgs
636//     }
637
638//     fn visit_seq_product<A: super::SeqProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
639//         visit_seq_product(&self.args, &self, tup)
640//     }
641
642//     fn visit_named_product<A: super::NamedProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
643//         visit_named_product(&self.args, &self, tup)
644//     }
645// }
646
647/// Deserialize, provided the fields' types, a product value with unnamed fields.
648pub fn visit_seq_product<'de, A: SeqProductAccess<'de>>(
649    elems: WithTypespace<[ProductTypeElement]>,
650    visitor: &impl ProductVisitor<'de>,
651    mut tup: A,
652) -> Result<ProductValue, A::Error> {
653    let elements = elems.ty().iter().enumerate().map(|(i, el)| {
654        tup.next_element_seed(elems.with(&el.algebraic_type))?
655            .ok_or_else(|| Error::invalid_product_length(i, visitor))
656    });
657    let elements = elements.collect::<Result<_, _>>()?;
658    Ok(ProductValue { elements })
659}
660
661/// Deserialize, provided the fields' types, a product value with named fields.
662pub fn visit_named_product<'de, A: super::NamedProductAccess<'de>>(
663    elems_tys: WithTypespace<[ProductTypeElement]>,
664    visitor: &impl ProductVisitor<'de>,
665    mut tup: A,
666) -> Result<ProductValue, A::Error> {
667    let elems = elems_tys.ty();
668    let mut elements = vec![None; elems.len()];
669    let kind = visitor.product_kind();
670
671    // Deserialize a product value corresponding to each product type field.
672    // This is worst case quadratic in complexity
673    // as fields can be specified out of order (value side) compared to `elems` (type side).
674    for _ in 0..elems.len() {
675        // Deserialize a field name, match against the element types.
676        let index = tup.get_field_ident(TupleNameVisitor { elems, kind })?.ok_or_else(|| {
677            // Couldn't deserialize a field name.
678            // Find the first field name we haven't filled an element for.
679            let missing = elements.iter().position(|field| field.is_none()).unwrap();
680            let field_name = elems[missing].name();
681            Error::missing_field(missing, field_name, visitor)
682        })?;
683
684        let element = &elems[index];
685
686        // By index we can select which element to deserialize a value for.
687        let slot = &mut elements[index];
688        if slot.is_some() {
689            return Err(Error::duplicate_field(index, element.name(), visitor));
690        }
691
692        // Deserialize the value for this field's type.
693        *slot = Some(tup.get_field_value_seed(elems_tys.with(&element.algebraic_type))?);
694    }
695
696    // Get rid of the `Option<_>` layer.
697    let elements = elements
698        .into_iter()
699        // We reached here, so we know nothing was missing, i.e., `None`.
700        .map(|x| x.unwrap_or_else(|| unreachable!("visit_named_product")))
701        .collect();
702
703    Ok(ProductValue { elements })
704}
705
706/// A visitor for extracting indices of field names in the elements of a [`ProductType`].
707struct TupleNameVisitor<'a> {
708    /// The elements of a product type, in order.
709    elems: &'a [ProductTypeElement],
710    /// The kind of product this is.
711    kind: ProductKind,
712}
713
714impl FieldNameVisitor<'_> for TupleNameVisitor<'_> {
715    // The index of the field name.
716    type Output = usize;
717
718    fn field_names(&self) -> impl '_ + Iterator<Item = Option<&str>> {
719        self.elems.iter().map(|f| f.name())
720    }
721
722    fn kind(&self) -> ProductKind {
723        self.kind
724    }
725
726    fn visit<E: Error>(self, name: &str) -> Result<Self::Output, E> {
727        // Finds the index of a field with `name`.
728        self.elems
729            .iter()
730            .position(|f| f.has_name(name))
731            .ok_or_else(|| Error::unknown_field_name(name, &self))
732    }
733
734    fn visit_seq(self, index: usize) -> Self::Output {
735        // Confirm that the index exists.
736        self.elems
737            .get(index)
738            .expect("`index` should exist when `visit_seq` is called");
739
740        index
741    }
742}
743
744impl_deserialize!([] spacetimedb_primitives::ArgId, de => u64::deserialize(de).map(Self));
745impl_deserialize!([] spacetimedb_primitives::TableId, de => u32::deserialize(de).map(Self));
746impl_deserialize!([] spacetimedb_primitives::ViewId, de => u32::deserialize(de).map(Self));
747impl_deserialize!([] spacetimedb_primitives::SequenceId, de => u32::deserialize(de).map(Self));
748impl_deserialize!([] spacetimedb_primitives::IndexId, de => u32::deserialize(de).map(Self));
749impl_deserialize!([] spacetimedb_primitives::ConstraintId, de => u32::deserialize(de).map(Self));
750impl_deserialize!([] spacetimedb_primitives::ColId, de => u16::deserialize(de).map(Self));
751impl_deserialize!([] spacetimedb_primitives::ScheduleId, de => u32::deserialize(de).map(Self));
752
753impl GrowingVec<ColId> for ColList {
754    fn with_capacity(cap: usize) -> Self {
755        Self::with_capacity(cap as u16)
756    }
757    fn push(&mut self, elem: ColId) {
758        self.push(elem);
759    }
760}
761impl_deserialize!([] spacetimedb_primitives::ColList, de => {
762    struct ColListVisitor;
763    impl<'de> ArrayVisitor<'de, ColId> for ColListVisitor {
764        type Output = ColList;
765
766        fn visit<A: ArrayAccess<'de, Element = ColId>>(self, vec: A) -> Result<Self::Output, A::Error> {
767            array_visit(vec)
768        }
769    }
770    de.deserialize_array(ColListVisitor)
771});
772impl_deserialize!([] spacetimedb_primitives::ColSet, de => ColList::deserialize(de).map(Into::into));
773
774#[cfg(feature = "blake3")]
775impl_deserialize!([] blake3::Hash, de => <[u8; blake3::OUT_LEN]>::deserialize(de).map(blake3::Hash::from_bytes));
776
777// TODO(perf): integrate Bytes with Deserializer to reduce copying
778impl_deserialize!([] bytes::Bytes, de => <Vec<u8>>::deserialize(de).map(Into::into));
779
780#[cfg(feature = "bytestring")]
781impl_deserialize!([] bytestring::ByteString, de => <String>::deserialize(de).map(Into::into));
782
783#[cfg(test)]
784mod test {
785    use crate::{
786        algebraic_value::{de::ValueDeserializer, ser::value_serialize},
787        bsatn,
788        serde::SerdeWrapper,
789        Deserialize, Serialize,
790    };
791    use core::fmt::Debug;
792
793    #[test]
794    fn roundtrip_tuples_in_different_data_formats() {
795        fn test<T: Serialize + for<'de> Deserialize<'de> + Eq + Debug>(x: T) {
796            let bsatn = bsatn::to_vec(&x).unwrap();
797            let y: T = bsatn::from_slice(&bsatn).unwrap();
798            assert_eq!(x, y);
799
800            let val = value_serialize(&x);
801            let y = T::deserialize(ValueDeserializer::new(val)).unwrap();
802            assert_eq!(x, y);
803
804            let json = serde_json::to_string(SerdeWrapper::from_ref(&x)).unwrap();
805            let SerdeWrapper(y) = serde_json::from_str::<SerdeWrapper<T>>(&json).unwrap();
806            assert_eq!(x, y);
807        }
808
809        test(());
810        test((true,));
811        test((1337u64, false));
812        test(((7331u64, false), 42u32, 24u8));
813    }
814}