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::{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
55impl_deserialize!([] (), de => de.deserialize_product(UnitVisitor));
56
57/// The `UnitVisitor` looks for a unit product.
58/// That is, it consumes nothing from the input.
59struct UnitVisitor;
60impl<'de> ProductVisitor<'de> for UnitVisitor {
61    type Output = ();
62
63    fn product_name(&self) -> Option<&str> {
64        None
65    }
66
67    fn product_len(&self) -> usize {
68        0
69    }
70
71    fn visit_seq_product<A: SeqProductAccess<'de>>(self, _prod: A) -> Result<Self::Output, A::Error> {
72        Ok(())
73    }
74
75    fn visit_named_product<A: super::NamedProductAccess<'de>>(self, _prod: A) -> Result<Self::Output, A::Error> {
76        Ok(())
77    }
78}
79
80impl<'de> Deserialize<'de> for u8 {
81    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
82        deserializer.deserialize_u8()
83    }
84
85    // Specialize `Vec<u8>` deserialization.
86    // This is more likely to compile down to a `memcpy`.
87    fn __deserialize_vec<D: Deserializer<'de>>(deserializer: D) -> Result<Vec<Self>, D::Error> {
88        deserializer.deserialize_bytes(OwnedSliceVisitor)
89    }
90
91    fn __deserialize_array<D: Deserializer<'de>, const N: usize>(deserializer: D) -> Result<[Self; N], D::Error> {
92        deserializer.deserialize_bytes(ByteArrayVisitor)
93    }
94}
95
96impl_deserialize!([] F32, de => f32::deserialize(de).map(Into::into));
97impl_deserialize!([] F64, de => f64::deserialize(de).map(Into::into));
98impl_deserialize!([] String, de => de.deserialize_str(OwnedSliceVisitor));
99impl_deserialize!([T: Deserialize<'de>] Vec<T>, de => T::__deserialize_vec(de));
100impl_deserialize!([T: Deserialize<'de>, const N: usize] SmallVec<[T; N]>, de => {
101    de.deserialize_array(BasicSmallVecVisitor)
102});
103impl_deserialize!([T: Deserialize<'de>, const N: usize] [T; N], de => T::__deserialize_array(de));
104impl_deserialize!([] Box<str>, de => String::deserialize(de).map(|s| s.into_boxed_str()));
105impl_deserialize!([T: Deserialize<'de>] Box<[T]>, de => Vec::deserialize(de).map(|s| s.into_boxed_slice()));
106impl_deserialize!([T: Deserialize<'de>] Rc<[T]>, de => Vec::deserialize(de).map(|s| s.into()));
107impl_deserialize!([T: Deserialize<'de>] Arc<[T]>, de => Vec::deserialize(de).map(|s| s.into()));
108
109/// The visitor converts the slice to its owned version.
110struct OwnedSliceVisitor;
111
112impl<T: ToOwned + ?Sized> SliceVisitor<'_, T> for OwnedSliceVisitor {
113    type Output = T::Owned;
114
115    fn visit<E: Error>(self, slice: &T) -> Result<Self::Output, E> {
116        Ok(slice.to_owned())
117    }
118
119    fn visit_owned<E: Error>(self, buf: T::Owned) -> Result<Self::Output, E> {
120        Ok(buf)
121    }
122}
123
124/// The visitor will convert the byte slice to `[u8; N]`.
125///
126/// When `slice.len() != N` an error will be raised.
127struct ByteArrayVisitor<const N: usize>;
128
129impl<const N: usize> SliceVisitor<'_, [u8]> for ByteArrayVisitor<N> {
130    type Output = [u8; N];
131
132    fn visit<E: Error>(self, slice: &[u8]) -> Result<Self::Output, E> {
133        slice.try_into().map_err(|_| {
134            Error::custom(if slice.len() > N {
135                "too many elements for array"
136            } else {
137                "too few elements for array"
138            })
139        })
140    }
141}
142
143impl_deserialize!([] &'de str, de => de.deserialize_str(BorrowedSliceVisitor));
144impl_deserialize!([] &'de [u8], de => de.deserialize_bytes(BorrowedSliceVisitor));
145
146/// The visitor returns the slice as-is and borrowed.
147pub(crate) struct BorrowedSliceVisitor;
148
149impl<'de, T: ToOwned + ?Sized + 'de> SliceVisitor<'de, T> for BorrowedSliceVisitor {
150    type Output = &'de T;
151
152    fn visit<E: Error>(self, _: &T) -> Result<Self::Output, E> {
153        Err(E::custom("expected *borrowed* slice"))
154    }
155
156    fn visit_borrowed<E: Error>(self, borrowed_slice: &'de T) -> Result<Self::Output, E> {
157        Ok(borrowed_slice)
158    }
159}
160
161impl_deserialize!([] Cow<'de, str>, de => de.deserialize_str(CowSliceVisitor));
162impl_deserialize!([] Cow<'de, [u8]>, de => de.deserialize_bytes(CowSliceVisitor));
163
164/// The visitor works with either owned or borrowed versions to produce `Cow<'de, T>`.
165struct CowSliceVisitor;
166
167impl<'de, T: ToOwned + ?Sized + 'de> SliceVisitor<'de, T> for CowSliceVisitor {
168    type Output = Cow<'de, T>;
169
170    fn visit<E: Error>(self, slice: &T) -> Result<Self::Output, E> {
171        self.visit_owned(slice.to_owned())
172    }
173
174    fn visit_owned<E: Error>(self, buf: <T as ToOwned>::Owned) -> Result<Self::Output, E> {
175        Ok(Cow::Owned(buf))
176    }
177
178    fn visit_borrowed<E: Error>(self, borrowed_slice: &'de T) -> Result<Self::Output, E> {
179        Ok(Cow::Borrowed(borrowed_slice))
180    }
181}
182
183impl_deserialize!([T: Deserialize<'de>] Box<T>, de => T::deserialize(de).map(Box::new));
184impl_deserialize!([T: Deserialize<'de>] Option<T>, de => de.deserialize_sum(OptionVisitor(PhantomData)));
185
186/// The visitor deserializes an `Option<T>`.
187struct OptionVisitor<T>(PhantomData<T>);
188
189impl<'de, T: Deserialize<'de>> SumVisitor<'de> for OptionVisitor<T> {
190    type Output = Option<T>;
191
192    fn sum_name(&self) -> Option<&str> {
193        Some("option")
194    }
195
196    fn is_option(&self) -> bool {
197        true
198    }
199
200    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
201        // Determine the variant.
202        let (some, data) = data.variant(self)?;
203
204        // Deserialize contents for it.
205        Ok(if some {
206            Some(data.deserialize()?)
207        } else {
208            data.deserialize::<()>()?;
209            None
210        })
211    }
212}
213
214impl<'de, T: Deserialize<'de>> VariantVisitor<'de> for OptionVisitor<T> {
215    type Output = bool;
216
217    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
218        ["some", "none"].into_iter()
219    }
220
221    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
222        match tag {
223            0 => Ok(true),
224            1 => Ok(false),
225            _ => Err(E::unknown_variant_tag(tag, &self)),
226        }
227    }
228
229    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
230        match name {
231            "some" => Ok(true),
232            "none" => Ok(false),
233            _ => Err(E::unknown_variant_name(name, &self)),
234        }
235    }
236}
237
238impl_deserialize!([T: Deserialize<'de>, E: Deserialize<'de>] Result<T, E>, de =>
239    de.deserialize_sum(ResultVisitor(PhantomData))
240);
241
242/// Visitor to deserialize a `Result<T, E>`.
243struct ResultVisitor<T, E>(PhantomData<(T, E)>);
244
245/// Variant determined by the [`VariantVisitor`] for `Result<T, E>`.
246enum ResultVariant {
247    Ok,
248    Err,
249}
250
251impl<'de, T: Deserialize<'de>, E: Deserialize<'de>> SumVisitor<'de> for ResultVisitor<T, E> {
252    type Output = Result<T, E>;
253
254    fn sum_name(&self) -> Option<&str> {
255        Some("result")
256    }
257
258    fn is_option(&self) -> bool {
259        false
260    }
261
262    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
263        let (variant, data) = data.variant(self)?;
264        Ok(match variant {
265            ResultVariant::Ok => Ok(data.deserialize()?),
266            ResultVariant::Err => Err(data.deserialize()?),
267        })
268    }
269}
270
271impl<'de, T: Deserialize<'de>, U: Deserialize<'de>> VariantVisitor<'de> for ResultVisitor<T, U> {
272    type Output = ResultVariant;
273
274    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
275        ["ok", "err"].into_iter()
276    }
277
278    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
279        match tag {
280            0 => Ok(ResultVariant::Ok),
281            1 => Ok(ResultVariant::Err),
282            _ => Err(E::unknown_variant_tag(tag, &self)),
283        }
284    }
285
286    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
287        match name {
288            "ok" => Ok(ResultVariant::Ok),
289            "err" => Ok(ResultVariant::Err),
290            _ => Err(E::unknown_variant_name(name, &self)),
291        }
292    }
293}
294
295/// The visitor deserializes a `Bound<T>`.
296#[derive(Clone, Copy)]
297pub struct WithBound<S>(pub S);
298
299impl<'de, S: Copy + DeserializeSeed<'de>> DeserializeSeed<'de> for WithBound<S> {
300    type Output = Bound<S::Output>;
301
302    fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Self::Output, D::Error> {
303        de.deserialize_sum(BoundVisitor(self.0))
304    }
305}
306
307/// The visitor deserializes a `Bound<T>`.
308struct BoundVisitor<S>(S);
309
310/// Variant determined by the [`BoundVisitor`] for `Bound<T>`.
311enum BoundVariant {
312    Included,
313    Excluded,
314    Unbounded,
315}
316
317impl<'de, S: Copy + DeserializeSeed<'de>> SumVisitor<'de> for BoundVisitor<S> {
318    type Output = Bound<S::Output>;
319
320    fn sum_name(&self) -> Option<&str> {
321        Some("bound")
322    }
323
324    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
325        // Determine the variant.
326        let this = self.0;
327        let (variant, data) = data.variant(self)?;
328
329        // Deserialize contents for it.
330        match variant {
331            BoundVariant::Included => data.deserialize_seed(this).map(Bound::Included),
332            BoundVariant::Excluded => data.deserialize_seed(this).map(Bound::Excluded),
333            BoundVariant::Unbounded => data.deserialize::<()>().map(|_| Bound::Unbounded),
334        }
335    }
336}
337
338impl<'de, T: Copy + DeserializeSeed<'de>> VariantVisitor<'de> for BoundVisitor<T> {
339    type Output = BoundVariant;
340
341    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
342        ["included", "excluded", "unbounded"].into_iter()
343    }
344
345    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
346        match tag {
347            0 => Ok(BoundVariant::Included),
348            1 => Ok(BoundVariant::Excluded),
349            // if this ever changes, edit crates/bindings/src/table.rs
350            2 => Ok(BoundVariant::Unbounded),
351            _ => Err(E::unknown_variant_tag(tag, &self)),
352        }
353    }
354
355    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
356        match name {
357            "included" => Ok(BoundVariant::Included),
358            "excluded" => Ok(BoundVariant::Excluded),
359            "unbounded" => Ok(BoundVariant::Unbounded),
360            _ => Err(E::unknown_variant_name(name, &self)),
361        }
362    }
363}
364
365impl<'de> DeserializeSeed<'de> for WithTypespace<'_, AlgebraicType> {
366    type Output = AlgebraicValue;
367
368    fn deserialize<D: Deserializer<'de>>(self, de: D) -> Result<Self::Output, D::Error> {
369        match self.ty() {
370            AlgebraicType::Ref(r) => self.resolve(*r).deserialize(de),
371            AlgebraicType::Sum(sum) => self.with(sum).deserialize(de).map(Into::into),
372            AlgebraicType::Product(prod) => self.with(prod).deserialize(de).map(Into::into),
373            AlgebraicType::Array(ty) => self.with(ty).deserialize(de).map(Into::into),
374            AlgebraicType::Bool => bool::deserialize(de).map(Into::into),
375            AlgebraicType::I8 => i8::deserialize(de).map(Into::into),
376            AlgebraicType::U8 => u8::deserialize(de).map(Into::into),
377            AlgebraicType::I16 => i16::deserialize(de).map(Into::into),
378            AlgebraicType::U16 => u16::deserialize(de).map(Into::into),
379            AlgebraicType::I32 => i32::deserialize(de).map(Into::into),
380            AlgebraicType::U32 => u32::deserialize(de).map(Into::into),
381            AlgebraicType::I64 => i64::deserialize(de).map(Into::into),
382            AlgebraicType::U64 => u64::deserialize(de).map(Into::into),
383            AlgebraicType::I128 => i128::deserialize(de).map(Into::into),
384            AlgebraicType::U128 => u128::deserialize(de).map(Into::into),
385            AlgebraicType::I256 => i256::deserialize(de).map(Into::into),
386            AlgebraicType::U256 => u256::deserialize(de).map(Into::into),
387            AlgebraicType::F32 => f32::deserialize(de).map(Into::into),
388            AlgebraicType::F64 => f64::deserialize(de).map(Into::into),
389            AlgebraicType::String => <Box<str>>::deserialize(de).map(Into::into),
390        }
391    }
392}
393
394impl<'de> DeserializeSeed<'de> for WithTypespace<'_, SumType> {
395    type Output = SumValue;
396
397    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
398        deserializer.deserialize_sum(self)
399    }
400}
401
402impl<'de> SumVisitor<'de> for WithTypespace<'_, SumType> {
403    type Output = SumValue;
404
405    fn sum_name(&self) -> Option<&str> {
406        None
407    }
408
409    fn is_option(&self) -> bool {
410        self.ty().as_option().is_some()
411    }
412
413    fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error> {
414        let (tag, data) = data.variant(self)?;
415        // Find the variant type by `tag`.
416        let variant_ty = self.map(|ty| &ty.variants[tag as usize].algebraic_type);
417
418        let value = Box::new(data.deserialize_seed(variant_ty)?);
419        Ok(SumValue { tag, value })
420    }
421}
422
423impl VariantVisitor<'_> for WithTypespace<'_, SumType> {
424    type Output = u8;
425
426    fn variant_names(&self) -> impl '_ + Iterator<Item = &str> {
427        // Provide the names known from the `SumType`.
428        self.ty().variants.iter().filter_map(|v| v.name())
429    }
430
431    fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E> {
432        // Verify that tag identifies a valid variant in `SumType`.
433        self.ty()
434            .variants
435            .get(tag as usize)
436            .ok_or_else(|| E::unknown_variant_tag(tag, &self))?;
437
438        Ok(tag)
439    }
440
441    fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E> {
442        // Translate the variant `name` to its tag.
443        self.ty()
444            .variants
445            .iter()
446            .position(|var| var.has_name(name))
447            .map(|pos| pos as u8)
448            .ok_or_else(|| E::unknown_variant_name(name, &self))
449    }
450}
451
452impl<'de> DeserializeSeed<'de> for WithTypespace<'_, ProductType> {
453    type Output = ProductValue;
454
455    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
456        deserializer.deserialize_product(self.map(|pt| &*pt.elements))
457    }
458}
459
460impl<'de> DeserializeSeed<'de> for WithTypespace<'_, [ProductTypeElement]> {
461    type Output = ProductValue;
462
463    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
464        deserializer.deserialize_product(self)
465    }
466}
467
468impl<'de> ProductVisitor<'de> for WithTypespace<'_, [ProductTypeElement]> {
469    type Output = ProductValue;
470
471    fn product_name(&self) -> Option<&str> {
472        None
473    }
474    fn product_len(&self) -> usize {
475        self.ty().len()
476    }
477
478    fn visit_seq_product<A: SeqProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
479        visit_seq_product(self, &self, tup)
480    }
481
482    fn visit_named_product<A: super::NamedProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
483        visit_named_product(self, &self, tup)
484    }
485}
486
487impl<'de> DeserializeSeed<'de> for WithTypespace<'_, ArrayType> {
488    type Output = ArrayValue;
489
490    fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
491        /// Deserialize a vector and `map` it to the appropriate `ArrayValue` variant.
492        fn de_array<'de, D: Deserializer<'de>, T: Deserialize<'de>>(
493            de: D,
494            map: impl FnOnce(Box<[T]>) -> ArrayValue,
495        ) -> Result<ArrayValue, D::Error> {
496            de.deserialize_array(BasicVecVisitor).map(<Box<[_]>>::from).map(map)
497        }
498
499        let mut ty = &*self.ty().elem_ty;
500
501        // Loop, resolving `Ref`s, until we reach a non-`Ref` type.
502        loop {
503            break match ty {
504                AlgebraicType::Ref(r) => {
505                    // The only arm that will loop.
506                    ty = self.resolve(*r).ty();
507                    continue;
508                }
509                AlgebraicType::Sum(ty) => deserializer
510                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
511                    .map(<Box<[_]>>::from)
512                    .map(ArrayValue::Sum),
513                AlgebraicType::Product(ty) => deserializer
514                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
515                    .map(<Box<[_]>>::from)
516                    .map(ArrayValue::Product),
517                AlgebraicType::Array(ty) => deserializer
518                    .deserialize_array_seed(BasicVecVisitor, self.with(ty))
519                    .map(<Box<[_]>>::from)
520                    .map(ArrayValue::Array),
521                &AlgebraicType::Bool => de_array(deserializer, ArrayValue::Bool),
522                &AlgebraicType::I8 => de_array(deserializer, ArrayValue::I8),
523                &AlgebraicType::U8 => deserializer
524                    .deserialize_bytes(OwnedSliceVisitor)
525                    .map(<Box<[_]>>::from)
526                    .map(ArrayValue::U8),
527                &AlgebraicType::I16 => de_array(deserializer, ArrayValue::I16),
528                &AlgebraicType::U16 => de_array(deserializer, ArrayValue::U16),
529                &AlgebraicType::I32 => de_array(deserializer, ArrayValue::I32),
530                &AlgebraicType::U32 => de_array(deserializer, ArrayValue::U32),
531                &AlgebraicType::I64 => de_array(deserializer, ArrayValue::I64),
532                &AlgebraicType::U64 => de_array(deserializer, ArrayValue::U64),
533                &AlgebraicType::I128 => de_array(deserializer, ArrayValue::I128),
534                &AlgebraicType::U128 => de_array(deserializer, ArrayValue::U128),
535                &AlgebraicType::I256 => de_array(deserializer, ArrayValue::I256),
536                &AlgebraicType::U256 => de_array(deserializer, ArrayValue::U256),
537                &AlgebraicType::F32 => de_array(deserializer, ArrayValue::F32),
538                &AlgebraicType::F64 => de_array(deserializer, ArrayValue::F64),
539                &AlgebraicType::String => de_array(deserializer, ArrayValue::String),
540            };
541        }
542    }
543}
544
545// impl<'de> DeserializeSeed<'de> for &ReducerDef {
546//     type Output = ProductValue;
547
548//     fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
549//         deserializer.deserialize_product(self)
550//     }
551// }
552
553// impl<'de> ProductVisitor<'de> for &ReducerDef {
554//     type Output = ProductValue;
555
556//     fn product_name(&self) -> Option<&str> {
557//         self.name.as_deref()
558//     }
559//     fn product_len(&self) -> usize {
560//         self.args.len()
561//     }
562//     fn product_kind(&self) -> ProductKind {
563//         ProductKind::ReducerArgs
564//     }
565
566//     fn visit_seq_product<A: super::SeqProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
567//         visit_seq_product(&self.args, &self, tup)
568//     }
569
570//     fn visit_named_product<A: super::NamedProductAccess<'de>>(self, tup: A) -> Result<Self::Output, A::Error> {
571//         visit_named_product(&self.args, &self, tup)
572//     }
573// }
574
575/// Deserialize, provided the fields' types, a product value with unnamed fields.
576pub fn visit_seq_product<'de, A: SeqProductAccess<'de>>(
577    elems: WithTypespace<[ProductTypeElement]>,
578    visitor: &impl ProductVisitor<'de>,
579    mut tup: A,
580) -> Result<ProductValue, A::Error> {
581    let elements = elems.ty().iter().enumerate().map(|(i, el)| {
582        tup.next_element_seed(elems.with(&el.algebraic_type))?
583            .ok_or_else(|| Error::invalid_product_length(i, visitor))
584    });
585    let elements = elements.collect::<Result<_, _>>()?;
586    Ok(ProductValue { elements })
587}
588
589/// Deserialize, provided the fields' types, a product value with named fields.
590pub fn visit_named_product<'de, A: super::NamedProductAccess<'de>>(
591    elems_tys: WithTypespace<[ProductTypeElement]>,
592    visitor: &impl ProductVisitor<'de>,
593    mut tup: A,
594) -> Result<ProductValue, A::Error> {
595    let elems = elems_tys.ty();
596    let mut elements = vec![None; elems.len()];
597    let kind = visitor.product_kind();
598
599    // Deserialize a product value corresponding to each product type field.
600    // This is worst case quadratic in complexity
601    // as fields can be specified out of order (value side) compared to `elems` (type side).
602    for _ in 0..elems.len() {
603        // Deserialize a field name, match against the element types, .
604        let index = tup.get_field_ident(TupleNameVisitor { elems, kind })?.ok_or_else(|| {
605            // Couldn't deserialize a field name.
606            // Find the first field name we haven't filled an element for.
607            let missing = elements.iter().position(|field| field.is_none()).unwrap();
608            let field_name = elems[missing].name();
609            Error::missing_field(missing, field_name, visitor)
610        })?;
611
612        let element = &elems[index];
613
614        // By index we can select which element to deserialize a value for.
615        let slot = &mut elements[index];
616        if slot.is_some() {
617            return Err(Error::duplicate_field(index, element.name(), visitor));
618        }
619
620        // Deserialize the value for this field's type.
621        *slot = Some(tup.get_field_value_seed(elems_tys.with(&element.algebraic_type))?);
622    }
623
624    // Get rid of the `Option<_>` layer.
625    let elements = elements
626        .into_iter()
627        // We reached here, so we know nothing was missing, i.e., `None`.
628        .map(|x| x.unwrap_or_else(|| unreachable!("visit_named_product")))
629        .collect();
630
631    Ok(ProductValue { elements })
632}
633
634/// A visitor for extracting indices of field names in the elements of a [`ProductType`].
635struct TupleNameVisitor<'a> {
636    /// The elements of a product type, in order.
637    elems: &'a [ProductTypeElement],
638    /// The kind of product this is.
639    kind: ProductKind,
640}
641
642impl FieldNameVisitor<'_> for TupleNameVisitor<'_> {
643    // The index of the field name.
644    type Output = usize;
645
646    fn field_names(&self) -> impl '_ + Iterator<Item = Option<&str>> {
647        self.elems.iter().map(|f| f.name())
648    }
649
650    fn kind(&self) -> ProductKind {
651        self.kind
652    }
653
654    fn visit<E: Error>(self, name: &str) -> Result<Self::Output, E> {
655        // Finds the index of a field with `name`.
656        self.elems
657            .iter()
658            .position(|f| f.has_name(name))
659            .ok_or_else(|| Error::unknown_field_name(name, &self))
660    }
661
662    fn visit_seq<E: Error>(self, index: usize, name: &str) -> Result<Self::Output, E> {
663        self.elems
664            .get(index)
665            .ok_or_else(|| Error::unknown_field_name(name, &self))?;
666
667        Ok(index)
668    }
669}
670
671impl_deserialize!([] spacetimedb_primitives::TableId, de => u32::deserialize(de).map(Self));
672impl_deserialize!([] spacetimedb_primitives::SequenceId, de => u32::deserialize(de).map(Self));
673impl_deserialize!([] spacetimedb_primitives::IndexId, de => u32::deserialize(de).map(Self));
674impl_deserialize!([] spacetimedb_primitives::ConstraintId, de => u32::deserialize(de).map(Self));
675impl_deserialize!([] spacetimedb_primitives::ColId, de => u16::deserialize(de).map(Self));
676impl_deserialize!([] spacetimedb_primitives::ScheduleId, de => u32::deserialize(de).map(Self));
677
678impl GrowingVec<ColId> for ColList {
679    fn with_capacity(cap: usize) -> Self {
680        Self::with_capacity(cap as u16)
681    }
682    fn push(&mut self, elem: ColId) {
683        self.push(elem);
684    }
685}
686impl_deserialize!([] spacetimedb_primitives::ColList, de => {
687    struct ColListVisitor;
688    impl<'de> ArrayVisitor<'de, ColId> for ColListVisitor {
689        type Output = ColList;
690
691        fn visit<A: ArrayAccess<'de, Element = ColId>>(self, vec: A) -> Result<Self::Output, A::Error> {
692            array_visit(vec)
693        }
694    }
695    de.deserialize_array(ColListVisitor)
696});
697impl_deserialize!([] spacetimedb_primitives::ColSet, de => ColList::deserialize(de).map(Into::into));
698
699#[cfg(feature = "blake3")]
700impl_deserialize!([] blake3::Hash, de => <[u8; blake3::OUT_LEN]>::deserialize(de).map(blake3::Hash::from_bytes));
701
702// TODO(perf): integrate Bytes with Deserializer to reduce copying
703impl_deserialize!([] bytes::Bytes, de => <Vec<u8>>::deserialize(de).map(Into::into));
704
705#[cfg(feature = "bytestring")]
706impl_deserialize!([] bytestring::ByteString, de => <String>::deserialize(de).map(Into::into));