mod impls;
#[cfg(any(test, feature = "serde"))]
pub mod serde;
#[doc(hidden)]
pub use impls::{visit_named_product, visit_seq_product, WithBound};
use crate::buffer::BufReader;
use crate::{bsatn, i256, u256};
use core::fmt;
use core::marker::PhantomData;
use smallvec::SmallVec;
use std::borrow::Borrow;
pub trait Deserializer<'de>: Sized {
type Error: Error;
fn deserialize_product<V: ProductVisitor<'de>>(self, visitor: V) -> Result<V::Output, Self::Error>;
fn validate_product<V: ProductVisitor<'de>>(self, visitor: V) -> Result<(), Self::Error> {
self.deserialize_product(visitor).map(|_| ())
}
fn deserialize_sum<V: SumVisitor<'de>>(self, visitor: V) -> Result<V::Output, Self::Error>;
fn validate_sum<V: SumVisitor<'de>>(self, visitor: V) -> Result<(), Self::Error> {
self.deserialize_sum(visitor).map(|_| ())
}
fn deserialize_bool(self) -> Result<bool, Self::Error>;
fn deserialize_u8(self) -> Result<u8, Self::Error>;
fn deserialize_u16(self) -> Result<u16, Self::Error>;
fn deserialize_u32(self) -> Result<u32, Self::Error>;
fn deserialize_u64(self) -> Result<u64, Self::Error>;
fn deserialize_u128(self) -> Result<u128, Self::Error>;
fn deserialize_u256(self) -> Result<u256, Self::Error>;
fn deserialize_i8(self) -> Result<i8, Self::Error>;
fn deserialize_i16(self) -> Result<i16, Self::Error>;
fn deserialize_i32(self) -> Result<i32, Self::Error>;
fn deserialize_i64(self) -> Result<i64, Self::Error>;
fn deserialize_i128(self) -> Result<i128, Self::Error>;
fn deserialize_i256(self) -> Result<i256, Self::Error>;
fn deserialize_f32(self) -> Result<f32, Self::Error>;
fn deserialize_f64(self) -> Result<f64, Self::Error>;
fn deserialize_str<V: SliceVisitor<'de, str>>(self, visitor: V) -> Result<V::Output, Self::Error>;
fn deserialize_str_slice(self) -> Result<&'de str, Self::Error> {
self.deserialize_str(BorrowedSliceVisitor)
}
fn deserialize_bytes<V: SliceVisitor<'de, [u8]>>(self, visitor: V) -> Result<V::Output, Self::Error>;
fn deserialize_array<V: ArrayVisitor<'de, T>, T: Deserialize<'de>>(
self,
visitor: V,
) -> Result<V::Output, Self::Error> {
self.deserialize_array_seed(visitor, PhantomData)
}
fn deserialize_array_seed<V: ArrayVisitor<'de, T::Output>, T: DeserializeSeed<'de> + Clone>(
self,
visitor: V,
seed: T,
) -> Result<V::Output, Self::Error>;
fn validate_array_seed<V: ArrayVisitor<'de, T::Output>, T: DeserializeSeed<'de> + Clone>(
self,
visitor: V,
seed: T,
) -> Result<(), Self::Error> {
self.deserialize_array_seed(visitor, seed).map(|_| ())
}
}
pub trait Error: Sized {
fn custom(msg: impl fmt::Display) -> Self;
fn named_products_not_supported() -> Self {
Self::custom("named products not supported")
}
fn invalid_product_length<'de, T: ProductVisitor<'de>>(len: usize, expected: &T) -> Self {
Self::custom(format_args!(
"invalid length {}, expected {}",
len,
fmt_invalid_len(expected)
))
}
fn missing_field<'de, T: ProductVisitor<'de>>(index: usize, field_name: Option<&str>, prod: &T) -> Self {
Self::custom(error_on_field("missing ", index, field_name, prod))
}
fn duplicate_field<'de, T: ProductVisitor<'de>>(index: usize, field_name: Option<&str>, prod: &T) -> Self {
Self::custom(error_on_field("duplicate ", index, field_name, prod))
}
fn unknown_field_name<'de, T: FieldNameVisitor<'de>>(field_name: &str, expected: &T) -> Self {
let el_ty = match expected.kind() {
ProductKind::Normal => "field",
ProductKind::ReducerArgs => "reducer argument",
};
match one_of_names(|| expected.field_names()) {
Some(one_of) => Self::custom(format_args!("unknown {el_ty} `{field_name}`, expected {one_of}")),
_ => Self::custom(format_args!("unknown {el_ty} `{field_name}`, there are no {el_ty}s")),
}
}
fn unknown_variant_tag<'de, T: SumVisitor<'de>>(tag: u8, expected: &T) -> Self {
Self::custom(format_args!(
"unknown tag {tag:#x} for sum type {}",
expected.sum_name().unwrap_or("<unknown>"),
))
}
fn unknown_variant_name<'de, T: VariantVisitor<'de>>(name: &str, expected: &T) -> Self {
match one_of_names(|| expected.variant_names().map(Some)) {
Some(one_of) => Self::custom(format_args!("unknown variant `{name}`, expected {one_of}",)),
_ => Self::custom(format_args!("unknown variant `{name}`, there are no variants")),
}
}
fn allocation_failed(size: usize) -> Self {
Self::custom(format_args!("allocation of {size} elements failed"))
}
}
pub struct FDisplay<F>(F);
impl<F: Fn(&mut fmt::Formatter) -> fmt::Result> fmt::Display for FDisplay<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(self.0)(f)
}
}
pub fn fmt_fn<F: Fn(&mut fmt::Formatter) -> fmt::Result>(f: F) -> FDisplay<F> {
FDisplay(f)
}
fn error_on_field<'a, 'de>(
problem: &'static str,
index: usize,
name: Option<&'a str>,
prod: &impl ProductVisitor<'de>,
) -> impl fmt::Display + 'a {
let field_kind = match prod.product_kind() {
ProductKind::Normal => "field",
ProductKind::ReducerArgs => "reducer argument",
};
fmt_fn(move |f| {
f.write_str(problem)?;
f.write_str(field_kind)?;
if let Some(name) = name {
write!(f, " `{name}`")
} else {
write!(f, " (index {index})")
}
})
}
fn fmt_invalid_len<'de>(
expected: &impl ProductVisitor<'de>,
) -> FDisplay<impl '_ + Fn(&mut fmt::Formatter) -> fmt::Result> {
fmt_fn(|f| {
let ty = match expected.product_kind() {
ProductKind::Normal => "product type",
ProductKind::ReducerArgs => "reducer args for",
};
let name = expected.product_name().unwrap_or("<product>");
let len = expected.product_len();
write!(f, "{ty} {name} with {len} elements")
})
}
pub trait ProductVisitor<'de>: Sized {
type Output;
fn product_name(&self) -> Option<&str>;
fn product_len(&self) -> usize;
fn product_kind(&self) -> ProductKind {
ProductKind::Normal
}
fn visit_seq_product<A: SeqProductAccess<'de>>(self, prod: A) -> Result<Self::Output, A::Error>;
fn visit_named_product<A: NamedProductAccess<'de>>(self, prod: A) -> Result<Self::Output, A::Error>;
fn validate_seq_product<A: SeqProductAccess<'de>>(self, prod: A) -> Result<(), A::Error> {
self.visit_seq_product(prod).map(|_| ())
}
fn validate_named_product<A: NamedProductAccess<'de>>(self, prod: A) -> Result<(), A::Error> {
self.visit_named_product(prod).map(|_| ())
}
}
#[derive(Clone, Copy)]
pub enum ProductKind {
Normal,
ReducerArgs,
}
pub trait SeqProductAccess<'de> {
type Error: Error;
fn next_element<T: Deserialize<'de>>(&mut self) -> Result<Option<T>, Self::Error> {
self.next_element_seed(PhantomData)
}
fn validate_next_element<T: Deserialize<'de>>(&mut self) -> Result<Option<()>, Self::Error> {
self.validate_next_element_seed(PhantomData::<T>)
}
fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Output>, Self::Error>;
fn validate_next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<()>, Self::Error> {
self.next_element_seed(seed).map(|opt| opt.map(|_| ()))
}
}
pub trait NamedProductAccess<'de> {
type Error: Error;
fn get_field_ident<V: FieldNameVisitor<'de>>(&mut self, visitor: V) -> Result<Option<V::Output>, Self::Error>;
fn get_field_value<T: Deserialize<'de>>(&mut self) -> Result<T, Self::Error> {
self.get_field_value_seed(PhantomData)
}
fn validate_field_value<T: Deserialize<'de>>(&mut self) -> Result<(), Self::Error> {
self.validate_field_value_seed(PhantomData::<T>)
}
fn get_field_value_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<T::Output, Self::Error>;
fn validate_field_value_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<(), Self::Error> {
self.get_field_value_seed(seed).map(|_| ())
}
}
pub trait FieldNameVisitor<'de> {
type Output;
fn kind(&self) -> ProductKind {
ProductKind::Normal
}
fn field_names(&self) -> impl '_ + Iterator<Item = Option<&str>>;
fn visit<E: Error>(self, name: &str) -> Result<Self::Output, E>;
fn visit_seq(self, index: usize) -> Self::Output;
}
pub trait SumVisitor<'de> {
type Output;
fn sum_name(&self) -> Option<&str>;
fn is_option(&self) -> bool {
false
}
fn visit_sum<A: SumAccess<'de>>(self, data: A) -> Result<Self::Output, A::Error>;
fn validate_sum<A: SumAccess<'de>>(self, data: A) -> Result<(), A::Error>;
}
pub trait SumAccess<'de> {
type Error: Error;
type Variant: VariantAccess<'de, Error = Self::Error>;
fn variant<V: VariantVisitor<'de>>(self, visitor: V) -> Result<(V::Output, Self::Variant), Self::Error>;
}
pub trait VariantVisitor<'de> {
type Output;
fn variant_names(&self) -> impl '_ + Iterator<Item = &str>;
fn visit_tag<E: Error>(self, tag: u8) -> Result<Self::Output, E>;
fn visit_name<E: Error>(self, name: &str) -> Result<Self::Output, E>;
}
pub trait VariantAccess<'de>: Sized {
type Error: Error;
fn deserialize<T: Deserialize<'de>>(self) -> Result<T, Self::Error> {
self.deserialize_seed(PhantomData)
}
fn deserialize_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Output, Self::Error>;
fn validate<T: Deserialize<'de>>(self) -> Result<(), Self::Error> {
self.validate_seed(PhantomData::<T>)
}
fn validate_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<(), Self::Error> {
self.deserialize_seed(seed).map(|_| ())
}
}
pub trait SliceVisitor<'de, T: ToOwned + ?Sized>: Sized {
type Output;
fn visit<E: Error>(self, slice: &T) -> Result<Self::Output, E>;
fn visit_owned<E: Error>(self, buf: T::Owned) -> Result<Self::Output, E> {
self.visit(buf.borrow())
}
fn visit_borrowed<E: Error>(self, borrowed_slice: &'de T) -> Result<Self::Output, E> {
self.visit(borrowed_slice)
}
}
pub trait ArrayVisitor<'de, T>: Sized {
type Output;
fn visit<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<Self::Output, A::Error>;
fn validate<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<(), A::Error> {
let _ = self.visit(vec)?;
Ok(())
}
}
pub trait ArrayAccess<'de> {
type Element;
type Error: Error;
fn next_element(&mut self) -> Result<Option<Self::Element>, Self::Error>;
fn validate_next_element(&mut self) -> Result<Option<()>, Self::Error> {
let opt = self.next_element()?;
Ok(opt.map(|_| ()))
}
fn size_hint(&self) -> Option<usize> {
None
}
}
pub trait DeserializeSeed<'de>: Sized {
type Output;
fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error>;
fn validate<D: Deserializer<'de>>(self, deserializer: D) -> Result<(), D::Error> {
let _ = self.deserialize(deserializer)?;
Ok(())
}
}
use crate::de::impls::BorrowedSliceVisitor;
pub use spacetimedb_bindings_macro::Deserialize;
pub trait Deserialize<'de>: Sized {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>;
#[doc(hidden)]
fn deserialize_from_bsatn<R: BufReader<'de>>(
deserializer: bsatn::Deserializer<'de, R>,
) -> Result<Self, bsatn::DecodeError> {
Self::deserialize(deserializer)
}
#[doc(hidden)]
#[inline(always)]
fn __deserialize_vec<D: Deserializer<'de>>(deserializer: D) -> Result<Vec<Self>, D::Error> {
deserializer.deserialize_array(BasicVecVisitor)
}
#[doc(hidden)]
#[inline(always)]
fn __deserialize_array<D: Deserializer<'de>, const N: usize>(deserializer: D) -> Result<[Self; N], D::Error> {
deserializer.deserialize_array(BasicArrayVisitor)
}
#[doc(hidden)]
#[inline(always)]
fn validate<D: Deserializer<'de>>(deserializer: D) -> Result<(), D::Error> {
let _ = Self::deserialize(deserializer)?;
Ok(())
}
}
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T: for<'de> Deserialize<'de>> DeserializeOwned for T {}
impl<'de, T: Deserialize<'de>> DeserializeSeed<'de> for PhantomData<T> {
type Output = T;
fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Output, D::Error> {
T::deserialize(deserializer)
}
}
pub trait GrowingVec<T> {
fn try_with_capacity<E: Error>(cap: usize) -> Result<Self, E>
where
Self: Sized;
fn push(&mut self, elem: T);
}
impl<T> GrowingVec<T> for Vec<T> {
fn try_with_capacity<E: Error>(cap: usize) -> Result<Self, E>
where
Self: Sized,
{
let mut vec = Vec::new();
vec.try_reserve_exact(cap).map_err(|_| E::allocation_failed(cap))?;
Ok(vec)
}
fn push(&mut self, elem: T) {
self.push(elem)
}
}
impl<T, const N: usize> GrowingVec<T> for SmallVec<[T; N]> {
fn try_with_capacity<E: Error>(cap: usize) -> Result<Self, E>
where
Self: Sized,
{
let mut vec = Self::new();
vec.try_reserve_exact(cap).map_err(|_| E::allocation_failed(cap))?;
Ok(vec)
}
fn push(&mut self, elem: T) {
self.push(elem)
}
}
pub fn array_visit<'de, A: ArrayAccess<'de>, V: GrowingVec<A::Element>>(mut access: A) -> Result<V, A::Error> {
let mut v = V::try_with_capacity(access.size_hint().unwrap_or(0))?;
while let Some(x) = access.next_element()? {
v.push(x)
}
Ok(v)
}
pub fn array_validate<'de, A: ArrayAccess<'de>>(mut access: A) -> Result<(), A::Error> {
while access.validate_next_element()?.is_some() {}
Ok(())
}
pub struct BasicVecVisitor;
impl<'de, T> ArrayVisitor<'de, T> for BasicVecVisitor {
type Output = Vec<T>;
fn visit<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<Self::Output, A::Error> {
array_visit(vec)
}
fn validate<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<(), A::Error> {
array_validate(vec)
}
}
pub struct BasicSmallVecVisitor<const N: usize>;
impl<'de, T, const N: usize> ArrayVisitor<'de, T> for BasicSmallVecVisitor<N> {
type Output = SmallVec<[T; N]>;
fn visit<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<Self::Output, A::Error> {
array_visit(vec)
}
fn validate<A: ArrayAccess<'de, Element = T>>(self, vec: A) -> Result<(), A::Error> {
array_validate(vec)
}
}
struct BasicArrayVisitor<const N: usize>;
impl<'de, T, const N: usize> ArrayVisitor<'de, T> for BasicArrayVisitor<N> {
type Output = [T; N];
fn visit<A: ArrayAccess<'de, Element = T>>(self, mut vec: A) -> Result<Self::Output, A::Error> {
let mut v = arrayvec::ArrayVec::<T, N>::new();
while let Some(el) = vec.next_element()? {
v.try_push(el)
.map_err(|_| Error::custom("too many elements for array"))?
}
v.into_inner().map_err(|_| Error::custom("too few elements for array"))
}
fn validate<A: ArrayAccess<'de, Element = T>>(self, mut vec: A) -> Result<(), A::Error> {
let mut count = 0;
while vec.next_element()?.is_some() {
count += 1;
}
if count > N {
return Err(Error::custom("too many elements for array"));
}
if count < N {
return Err(Error::custom("too few elements for array"));
}
Ok(())
}
}
fn one_of_names<'a, I: Iterator<Item = Option<&'a str>>>(names: impl Fn() -> I) -> Option<impl fmt::Display> {
let count = names().count();
(count != 0).then(move || {
fmt_fn(move |f| {
let mut anon_name = 0;
for (index, mut name) in names().enumerate() {
let mut name_buf: String = String::new();
let name = name.get_or_insert_with(|| {
name_buf = format!("{anon_name}");
anon_name += 1;
&name_buf
});
match (count, index) {
(1, _) => write!(f, "`{name}`"),
(2, 1) => write!(f, "`{name}`"),
(2, 2) => write!(f, "`or `{name}`"),
(_, 1) => write!(f, "one of `{name}`"),
(c, i) if i < c => write!(f, ", `{name}`"),
(_, _) => write!(f, ", `, or {name}`"),
}?;
}
Ok(())
})
})
}
pub struct NoneAccess<E>(PhantomData<E>);
impl<E: Error> NoneAccess<E> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<E: Error> Default for NoneAccess<E> {
fn default() -> Self {
Self::new()
}
}
impl<'de, E: Error> SumAccess<'de> for NoneAccess<E> {
type Error = E;
type Variant = Self;
fn variant<V: VariantVisitor<'de>>(self, visitor: V) -> Result<(V::Output, Self::Variant), Self::Error> {
visitor.visit_name("none").map(|var| (var, self))
}
}
impl<'de, E: Error> VariantAccess<'de> for NoneAccess<E> {
type Error = E;
fn deserialize_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Output, Self::Error> {
seed.deserialize(UnitAccess::new())
}
}
pub struct SomeAccess<D>(D);
impl<D> SomeAccess<D> {
pub fn new(de: D) -> Self {
Self(de)
}
}
impl<'de, D: Deserializer<'de>> SumAccess<'de> for SomeAccess<D> {
type Error = D::Error;
type Variant = Self;
fn variant<V: VariantVisitor<'de>>(self, visitor: V) -> Result<(V::Output, Self::Variant), Self::Error> {
visitor.visit_name("some").map(|var| (var, self))
}
}
impl<'de, D: Deserializer<'de>> VariantAccess<'de> for SomeAccess<D> {
type Error = D::Error;
fn deserialize_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Output, Self::Error> {
seed.deserialize(self.0)
}
fn validate_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<(), Self::Error> {
seed.validate(self.0)
}
}
pub struct UnitAccess<E>(PhantomData<E>);
impl<E: Error> UnitAccess<E> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<E: Error> Default for UnitAccess<E> {
fn default() -> Self {
Self::new()
}
}
impl<'de, E: Error> SeqProductAccess<'de> for UnitAccess<E> {
type Error = E;
fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, _seed: T) -> Result<Option<T::Output>, Self::Error> {
Ok(None)
}
}
impl<'de, E: Error> NamedProductAccess<'de> for UnitAccess<E> {
type Error = E;
fn get_field_ident<V: FieldNameVisitor<'de>>(&mut self, _visitor: V) -> Result<Option<V::Output>, Self::Error> {
Ok(None)
}
fn get_field_value_seed<T: DeserializeSeed<'de>>(&mut self, _seed: T) -> Result<T::Output, Self::Error> {
unreachable!()
}
}
impl<'de, E: Error> Deserializer<'de> for UnitAccess<E> {
type Error = E;
fn deserialize_product<V: ProductVisitor<'de>>(self, visitor: V) -> Result<V::Output, Self::Error> {
visitor.visit_seq_product(self)
}
fn deserialize_sum<V: SumVisitor<'de>>(self, _visitor: V) -> Result<V::Output, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_bool(self) -> Result<bool, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u8(self) -> Result<u8, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u16(self) -> Result<u16, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u32(self) -> Result<u32, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u64(self) -> Result<u64, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u128(self) -> Result<u128, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_u256(self) -> Result<u256, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i8(self) -> Result<i8, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i16(self) -> Result<i16, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i32(self) -> Result<i32, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i64(self) -> Result<i64, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i128(self) -> Result<i128, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_i256(self) -> Result<i256, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_f32(self) -> Result<f32, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_f64(self) -> Result<f64, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_str<V: SliceVisitor<'de, str>>(self, _visitor: V) -> Result<V::Output, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_bytes<V: SliceVisitor<'de, [u8]>>(self, _visitor: V) -> Result<V::Output, Self::Error> {
Err(E::custom("invalid type"))
}
fn deserialize_array_seed<V: ArrayVisitor<'de, T::Output>, T: DeserializeSeed<'de> + Clone>(
self,
_visitor: V,
_seed: T,
) -> Result<V::Output, Self::Error> {
Err(E::custom("invalid type"))
}
}