1pub mod algebraic_type;
2mod algebraic_type_ref;
3pub mod algebraic_value;
4mod algebraic_value_hash;
5pub mod array_type;
6pub mod array_value;
7pub mod bsatn;
8pub mod buffer;
9pub mod convert;
10pub mod de;
11pub mod hash;
12pub mod hex;
13pub mod layout;
14#[cfg(feature = "memory-usage")]
15mod memory_usage_impls;
16#[cfg(feature = "memory-usage")]
17pub use spacetimedb_memory_usage as memory_usage;
18pub mod meta_type;
19pub mod primitives;
20pub mod product_type;
21pub mod product_type_element;
22pub mod product_value;
23pub mod raw_identifier;
24mod resolve_refs;
25pub mod satn;
26pub mod ser;
27pub mod size_of;
28pub mod sum_type;
29pub mod sum_type_variant;
30pub mod sum_value;
31pub mod time_duration;
32pub mod timestamp;
33pub mod typespace;
34pub mod uuid;
35
36#[cfg(any(test, feature = "proptest"))]
37pub mod proptest;
38
39#[cfg(any(test, feature = "serde"))]
40pub mod serde {
41 pub use crate::de::serde::{deserialize_from as deserialize, SerdeDeserializer};
42 pub use crate::ser::serde::{serialize_to as serialize, SerdeSerializer};
43
44 #[repr(transparent)]
46 pub struct SerdeError<E>(pub E);
47
48 #[repr(transparent)]
55 pub struct SerdeWrapper<T: ?Sized>(pub T);
56
57 impl<T: ?Sized> SerdeWrapper<T> {
58 pub fn new(t: T) -> Self
60 where
61 T: Sized,
62 {
63 Self(t)
64 }
65
66 pub fn from_ref(t: &T) -> &Self {
68 unsafe { &*(t as *const T as *const SerdeWrapper<T>) }
70 }
71 }
72}
73
74#[doc(hidden)]
77pub use crate as sats;
78use crate::raw_identifier::RawIdentifier;
79
80pub use algebraic_type::AlgebraicType;
81pub use algebraic_type_ref::AlgebraicTypeRef;
82pub use algebraic_value::{i256, u256, AlgebraicValue, F32, F64};
83pub use algebraic_value_hash::hash_bsatn_array;
84pub use array_type::ArrayType;
85pub use array_value::ArrayValue;
86pub use product_type::ProductType;
87pub use product_type_element::ProductTypeElement;
88pub use product_value::ProductValue;
89pub use sum_type::SumType;
90pub use sum_type_variant::SumTypeVariant;
91pub use sum_value::SumValue;
92pub use typespace::{GroundSpacetimeType, SpacetimeType, Typespace};
93
94pub use de::Deserialize;
95pub use ser::Serialize;
96
97pub trait Value {
101 type Type;
103}
104
105impl<T: Value> Value for Box<[T]> {
106 type Type = T::Type;
108}
109
110pub struct ValueWithType<'a, T: Value> {
112 ty: WithTypespace<'a, T::Type>,
114 val: &'a T,
116}
117
118impl<T: Value> Copy for ValueWithType<'_, T> {}
119impl<T: Value> Clone for ValueWithType<'_, T> {
120 fn clone(&self) -> Self {
121 *self
122 }
123}
124
125impl<'a, T: Value> ValueWithType<'a, T> {
126 pub fn new(ty: WithTypespace<'a, T::Type>, val: &'a T) -> Self {
128 Self { ty, val }
129 }
130
131 pub fn value(&self) -> &'a T {
133 self.val
134 }
135
136 pub fn ty(&self) -> &'a T::Type {
138 self.ty.ty
139 }
140
141 pub fn ty_s(&self) -> WithTypespace<'a, T::Type> {
142 self.ty
143 }
144
145 pub fn typespace(&self) -> &'a Typespace {
147 self.ty.typespace
148 }
149
150 pub fn with<'b, U: Value>(&self, ty: &'b U::Type, val: &'b U) -> ValueWithType<'b, U>
152 where
153 'a: 'b,
154 {
155 ValueWithType {
156 ty: self.ty.with(ty),
157 val,
158 }
159 }
160}
161
162impl<'a, T: Value> ValueWithType<'a, Box<[T]>> {
163 pub fn iter(&self) -> impl Iterator<Item = ValueWithType<'a, T>> + use<'_, 'a, T> {
164 self.value().iter().map(|val| ValueWithType { ty: self.ty, val })
165 }
166}
167
168impl<T: Value + PartialEq> PartialEq<T> for ValueWithType<'_, T> {
169 fn eq(&self, other: &T) -> bool {
170 self.val == other
171 }
172}
173
174use core::fmt;
175
176impl<T: fmt::Debug + Value<Type: fmt::Debug>> fmt::Debug for ValueWithType<'_, T> {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 f.debug_struct("ValueWithType")
179 .field("type", self.ty())
180 .field("value", self.value())
181 .finish()
182 }
183}
184
185#[derive(Debug)]
187pub struct WithTypespace<'a, T: ?Sized> {
188 typespace: &'a Typespace,
190 ty: &'a T,
192}
193
194impl<T: ?Sized> Copy for WithTypespace<'_, T> {}
195impl<T: ?Sized> Clone for WithTypespace<'_, T> {
196 fn clone(&self) -> Self {
197 *self
198 }
199}
200
201impl<'a, T: ?Sized> WithTypespace<'a, T> {
202 pub const fn new(typespace: &'a Typespace, ty: &'a T) -> Self {
204 Self { typespace, ty }
205 }
206
207 pub const fn empty(ty: &'a T) -> Self {
209 Self::new(Typespace::EMPTY, ty)
210 }
211
212 pub const fn ty(&self) -> &'a T {
214 self.ty
215 }
216
217 pub const fn typespace(&self) -> &'a Typespace {
219 self.typespace
220 }
221
222 pub fn with<'b, U>(&self, ty: &'b U) -> WithTypespace<'b, U>
224 where
225 'a: 'b,
226 {
227 WithTypespace {
228 typespace: self.typespace,
229 ty,
230 }
231 }
232
233 pub(crate) fn iter_with<U: 'a, I: IntoIterator<Item = &'a U>>(&self, tys: I) -> IterWithTypespace<'a, I::IntoIter> {
234 IterWithTypespace {
235 typespace: self.typespace,
236 iter: tys.into_iter(),
237 }
238 }
239
240 pub fn with_value<'b, V: Value<Type = T>>(&self, val: &'b V) -> ValueWithType<'b, V>
242 where
243 'a: 'b,
244 {
245 ValueWithType::new(*self, val)
246 }
247
248 pub fn resolve(&self, r: AlgebraicTypeRef) -> WithTypespace<'a, AlgebraicType> {
252 WithTypespace {
253 typespace: self.typespace,
254 ty: &self.typespace[r],
255 }
256 }
257
258 pub fn map<U: ?Sized>(&self, f: impl FnOnce(&'a T) -> &'a U) -> WithTypespace<'a, U> {
263 WithTypespace {
264 typespace: self.typespace,
265 ty: f(self.ty),
266 }
267 }
268}
269
270pub struct IterWithTypespace<'a, I> {
271 typespace: &'a Typespace,
272 iter: I,
273}
274
275impl<'a, I, T: 'a> Iterator for IterWithTypespace<'a, I>
276where
277 I: Iterator<Item = &'a T>,
278{
279 type Item = WithTypespace<'a, T>;
280 fn next(&mut self) -> Option<Self::Item> {
281 self.iter.next().map(|ty| self.typespace.with_type(ty))
282 }
283 fn size_hint(&self) -> (usize, Option<usize>) {
284 self.iter.size_hint()
285 }
286}
287
288impl<'a, I, T: 'a> ExactSizeIterator for IterWithTypespace<'a, I>
289where
290 I: ExactSizeIterator<Item = &'a T>,
291{
292 fn len(&self) -> usize {
293 self.iter.len()
294 }
295}
296
297#[macro_export]
299#[doc(hidden)]
300macro_rules! __make_register_reftype {
301 ($ty:ty, $name:literal) => {};
302}
303
304fn dbg_aggregate_name(opt: &Option<RawIdentifier>) -> &dyn std::fmt::Debug {
306 opt.as_ref().map_or(opt, |s| s)
307}