spacetimedb_sats/
array_value.rs

1use crate::{i256, u256};
2use crate::{AlgebraicType, AlgebraicValue, ArrayType, ProductValue, SumValue, F32, F64};
3use core::fmt;
4
5/// An array value in "monomorphized form".
6///
7/// Arrays are represented in this way monomorphized fashion for efficiency
8/// rather than unnecessary indirections and tags of `AlgebraicValue`.
9/// We can do this as we know statically that the type of each element is the same
10/// as arrays are homogenous dynamically sized product types.
11#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
12pub enum ArrayValue {
13    /// An array of [`SumValue`]s.
14    Sum(Box<[SumValue]>),
15    /// An array of [`ProductValue`]s.
16    Product(Box<[ProductValue]>),
17    /// An array of [`bool`]s.
18    Bool(Box<[bool]>),
19    /// An array of [`i8`]s.
20    I8(Box<[i8]>),
21    /// An array of [`u8`]s.
22    U8(Box<[u8]>),
23    /// An array of [`i16`]s.
24    I16(Box<[i16]>),
25    /// An array of [`u16`]s.
26    U16(Box<[u16]>),
27    /// An array of [`i32`]s.
28    I32(Box<[i32]>),
29    /// An array of [`u32`]s.
30    U32(Box<[u32]>),
31    /// An array of [`i64`]s.
32    I64(Box<[i64]>),
33    /// An array of [`u64`]s.
34    U64(Box<[u64]>),
35    /// An array of [`i128`]s.
36    I128(Box<[i128]>),
37    /// An array of [`u128`]s.
38    U128(Box<[u128]>),
39    /// An array of [`i256`]s.
40    I256(Box<[i256]>),
41    /// An array of [`u256`]s.
42    U256(Box<[u256]>),
43    /// An array of totally ordered [`F32`]s.
44    F32(Box<[F32]>),
45    /// An array of totally ordered [`F64`]s.
46    F64(Box<[F64]>),
47    /// An array of UTF-8 strings.
48    String(Box<[Box<str>]>),
49    /// An array of arrays.
50    Array(Box<[ArrayValue]>),
51}
52
53impl crate::Value for ArrayValue {
54    type Type = ArrayType;
55}
56
57impl ArrayValue {
58    /// Determines (infers / synthesises) the type of the value.
59    pub(crate) fn type_of(&self) -> Option<ArrayType> {
60        let elem_ty = Box::new(match self {
61            Self::Sum(_) => None,
62            Self::Product(v) => AlgebraicValue::type_of_product(v.first()?),
63            Self::Bool(_) => Some(AlgebraicType::Bool),
64            Self::I8(_) => Some(AlgebraicType::I8),
65            Self::U8(_) => Some(AlgebraicType::U8),
66            Self::I16(_) => Some(AlgebraicType::I16),
67            Self::U16(_) => Some(AlgebraicType::U16),
68            Self::I32(_) => Some(AlgebraicType::I32),
69            Self::U32(_) => Some(AlgebraicType::U32),
70            Self::I64(_) => Some(AlgebraicType::I64),
71            Self::U64(_) => Some(AlgebraicType::U64),
72            Self::I128(_) => Some(AlgebraicType::I128),
73            Self::U128(_) => Some(AlgebraicType::U128),
74            Self::I256(_) => Some(AlgebraicType::I256),
75            Self::U256(_) => Some(AlgebraicType::U256),
76            Self::F32(_) => Some(AlgebraicType::F32),
77            Self::F64(_) => Some(AlgebraicType::F64),
78            Self::String(_) => Some(AlgebraicType::String),
79            Self::Array(v) => Some(v.first()?.type_of()?.into()),
80        }?);
81        Some(ArrayType { elem_ty })
82    }
83
84    /// Returns the length of the array.
85    pub fn len(&self) -> usize {
86        match self {
87            Self::Sum(v) => v.len(),
88            Self::Product(v) => v.len(),
89            Self::Bool(v) => v.len(),
90            Self::I8(v) => v.len(),
91            Self::U8(v) => v.len(),
92            Self::I16(v) => v.len(),
93            Self::U16(v) => v.len(),
94            Self::I32(v) => v.len(),
95            Self::U32(v) => v.len(),
96            Self::I64(v) => v.len(),
97            Self::U64(v) => v.len(),
98            Self::I128(v) => v.len(),
99            Self::U128(v) => v.len(),
100            Self::I256(v) => v.len(),
101            Self::U256(v) => v.len(),
102            Self::F32(v) => v.len(),
103            Self::F64(v) => v.len(),
104            Self::String(v) => v.len(),
105            Self::Array(v) => v.len(),
106        }
107    }
108
109    /// Returns whether the array is empty.
110    #[must_use]
111    pub fn is_empty(&self) -> bool {
112        self.len() == 0
113    }
114
115    /// Returns a cloning iterator on the elements of `self` as `AlgebraicValue`s.
116    pub fn iter_cloned(&self) -> ArrayValueIterCloned {
117        match self {
118            ArrayValue::Sum(v) => ArrayValueIterCloned::Sum(v.iter()),
119            ArrayValue::Product(v) => ArrayValueIterCloned::Product(v.iter()),
120            ArrayValue::Bool(v) => ArrayValueIterCloned::Bool(v.iter()),
121            ArrayValue::I8(v) => ArrayValueIterCloned::I8(v.iter()),
122            ArrayValue::U8(v) => ArrayValueIterCloned::U8(v.iter()),
123            ArrayValue::I16(v) => ArrayValueIterCloned::I16(v.iter()),
124            ArrayValue::U16(v) => ArrayValueIterCloned::U16(v.iter()),
125            ArrayValue::I32(v) => ArrayValueIterCloned::I32(v.iter()),
126            ArrayValue::U32(v) => ArrayValueIterCloned::U32(v.iter()),
127            ArrayValue::I64(v) => ArrayValueIterCloned::I64(v.iter()),
128            ArrayValue::U64(v) => ArrayValueIterCloned::U64(v.iter()),
129            ArrayValue::I128(v) => ArrayValueIterCloned::I128(v.iter()),
130            ArrayValue::U128(v) => ArrayValueIterCloned::U128(v.iter()),
131            ArrayValue::I256(v) => ArrayValueIterCloned::I256(v.iter()),
132            ArrayValue::U256(v) => ArrayValueIterCloned::U256(v.iter()),
133            ArrayValue::F32(v) => ArrayValueIterCloned::F32(v.iter()),
134            ArrayValue::F64(v) => ArrayValueIterCloned::F64(v.iter()),
135            ArrayValue::String(v) => ArrayValueIterCloned::String(v.iter()),
136            ArrayValue::Array(v) => ArrayValueIterCloned::Array(v.iter()),
137        }
138    }
139}
140
141impl Default for ArrayValue {
142    /// The default `ArrayValue` is an empty array of sum values.
143    fn default() -> Self {
144        Self::from(<[crate::SumValue; 0]>::default())
145    }
146}
147
148macro_rules! impl_from_array {
149    ($el:ty, $var:ident) => {
150        impl<const N: usize> From<[$el; N]> for ArrayValue {
151            fn from(v: [$el; N]) -> Self {
152                let vec: Box<[_]> = v.into();
153                vec.into()
154            }
155        }
156
157        // Exists for convenience.
158        impl From<Box<[$el]>> for ArrayValue {
159            fn from(v: Box<[$el]>) -> Self {
160                Self::$var(v)
161            }
162        }
163    };
164}
165
166impl_from_array!(crate::SumValue, Sum);
167impl_from_array!(crate::ProductValue, Product);
168impl_from_array!(bool, Bool);
169impl_from_array!(i8, I8);
170impl_from_array!(u8, U8);
171impl_from_array!(i16, I16);
172impl_from_array!(u16, U16);
173impl_from_array!(i32, I32);
174impl_from_array!(u32, U32);
175impl_from_array!(i64, I64);
176impl_from_array!(u64, U64);
177impl_from_array!(i128, I128);
178impl_from_array!(u128, U128);
179impl_from_array!(i256, I256);
180impl_from_array!(u256, U256);
181impl_from_array!(F32, F32);
182impl_from_array!(F64, F64);
183impl_from_array!(Box<str>, String);
184impl_from_array!(ArrayValue, Array);
185
186impl ArrayValue {
187    /// Returns `self` as `&dyn Debug`.
188    fn as_dyn_debug(&self) -> &dyn fmt::Debug {
189        match self {
190            Self::Sum(v) => v,
191            Self::Product(v) => v,
192            Self::Bool(v) => v,
193            Self::I8(v) => v,
194            Self::U8(v) => v,
195            Self::I16(v) => v,
196            Self::U16(v) => v,
197            Self::I32(v) => v,
198            Self::U32(v) => v,
199            Self::I64(v) => v,
200            Self::U64(v) => v,
201            Self::I128(v) => v,
202            Self::U128(v) => v,
203            Self::I256(v) => v,
204            Self::U256(v) => v,
205            Self::F32(v) => v,
206            Self::F64(v) => v,
207            Self::String(v) => v,
208            Self::Array(v) => v,
209        }
210    }
211}
212impl fmt::Debug for ArrayValue {
213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214        self.as_dyn_debug().fmt(f)
215    }
216}
217
218impl IntoIterator for ArrayValue {
219    type Item = AlgebraicValue;
220
221    type IntoIter = ArrayValueIntoIter;
222
223    fn into_iter(self) -> Self::IntoIter {
224        match self {
225            ArrayValue::Sum(v) => ArrayValueIntoIter::Sum(Vec::from(v).into_iter()),
226            ArrayValue::Product(v) => ArrayValueIntoIter::Product(Vec::from(v).into_iter()),
227            ArrayValue::Bool(v) => ArrayValueIntoIter::Bool(Vec::from(v).into_iter()),
228            ArrayValue::I8(v) => ArrayValueIntoIter::I8(Vec::from(v).into_iter()),
229            ArrayValue::U8(v) => ArrayValueIntoIter::U8(Vec::from(v).into_iter()),
230            ArrayValue::I16(v) => ArrayValueIntoIter::I16(Vec::from(v).into_iter()),
231            ArrayValue::U16(v) => ArrayValueIntoIter::U16(Vec::from(v).into_iter()),
232            ArrayValue::I32(v) => ArrayValueIntoIter::I32(Vec::from(v).into_iter()),
233            ArrayValue::U32(v) => ArrayValueIntoIter::U32(Vec::from(v).into_iter()),
234            ArrayValue::I64(v) => ArrayValueIntoIter::I64(Vec::from(v).into_iter()),
235            ArrayValue::U64(v) => ArrayValueIntoIter::U64(Vec::from(v).into_iter()),
236            ArrayValue::I128(v) => ArrayValueIntoIter::I128(Vec::from(v).into_iter()),
237            ArrayValue::U128(v) => ArrayValueIntoIter::U128(Vec::from(v).into_iter()),
238            ArrayValue::I256(v) => ArrayValueIntoIter::I256(Vec::from(v).into_iter()),
239            ArrayValue::U256(v) => ArrayValueIntoIter::U256(Vec::from(v).into_iter()),
240            ArrayValue::F32(v) => ArrayValueIntoIter::F32(Vec::from(v).into_iter()),
241            ArrayValue::F64(v) => ArrayValueIntoIter::F64(Vec::from(v).into_iter()),
242            ArrayValue::String(v) => ArrayValueIntoIter::String(Vec::from(v).into_iter()),
243            ArrayValue::Array(v) => ArrayValueIntoIter::Array(Vec::from(v).into_iter()),
244        }
245    }
246}
247
248/// A by-value iterator on the elements of an `ArrayValue` as `AlgebraicValue`s.
249pub enum ArrayValueIntoIter {
250    /// An iterator on a sum value array.
251    Sum(std::vec::IntoIter<SumValue>),
252    /// An iterator on a product value array.
253    Product(std::vec::IntoIter<ProductValue>),
254    /// An iterator on a [`bool`] array.
255    Bool(std::vec::IntoIter<bool>),
256    /// An iterator on an [`i8`] array.
257    I8(std::vec::IntoIter<i8>),
258    /// An iterator on a [`u8`] array.
259    U8(std::vec::IntoIter<u8>),
260    /// An iterator on an [`i16`] array.
261    I16(std::vec::IntoIter<i16>),
262    /// An iterator on a [`u16`] array.
263    U16(std::vec::IntoIter<u16>),
264    /// An iterator on an [`i32`] array.
265    I32(std::vec::IntoIter<i32>),
266    /// An iterator on a [`u32`] array.
267    U32(std::vec::IntoIter<u32>),
268    /// An iterator on an [`i64`] array.
269    I64(std::vec::IntoIter<i64>),
270    /// An iterator on a [`u64`] array.
271    U64(std::vec::IntoIter<u64>),
272    /// An iterator on an [`i128`] array.
273    I128(std::vec::IntoIter<i128>),
274    /// An iterator on a [`u128`] array.
275    U128(std::vec::IntoIter<u128>),
276    /// An iterator on an [`i256`] array.
277    I256(std::vec::IntoIter<i256>),
278    /// An iterator on a [`u256`] array.
279    U256(std::vec::IntoIter<u256>),
280    /// An iterator on a [`F32`] array.
281    F32(std::vec::IntoIter<F32>),
282    /// An iterator on a [`F64`] array.
283    F64(std::vec::IntoIter<F64>),
284    /// An iterator on an array of UTF-8 strings.
285    String(std::vec::IntoIter<Box<str>>),
286    /// An iterator on an array of arrays.
287    Array(std::vec::IntoIter<ArrayValue>),
288}
289
290impl Iterator for ArrayValueIntoIter {
291    type Item = AlgebraicValue;
292
293    fn next(&mut self) -> Option<Self::Item> {
294        match self {
295            ArrayValueIntoIter::Sum(it) => it.next().map(Into::into),
296            ArrayValueIntoIter::Product(it) => it.next().map(Into::into),
297            ArrayValueIntoIter::Bool(it) => it.next().map(Into::into),
298            ArrayValueIntoIter::I8(it) => it.next().map(Into::into),
299            ArrayValueIntoIter::U8(it) => it.next().map(Into::into),
300            ArrayValueIntoIter::I16(it) => it.next().map(Into::into),
301            ArrayValueIntoIter::U16(it) => it.next().map(Into::into),
302            ArrayValueIntoIter::I32(it) => it.next().map(Into::into),
303            ArrayValueIntoIter::U32(it) => it.next().map(Into::into),
304            ArrayValueIntoIter::I64(it) => it.next().map(Into::into),
305            ArrayValueIntoIter::U64(it) => it.next().map(Into::into),
306            ArrayValueIntoIter::I128(it) => it.next().map(Into::into),
307            ArrayValueIntoIter::U128(it) => it.next().map(Into::into),
308            ArrayValueIntoIter::I256(it) => it.next().map(Into::into),
309            ArrayValueIntoIter::U256(it) => it.next().map(Into::into),
310            ArrayValueIntoIter::F32(it) => it.next().map(Into::into),
311            ArrayValueIntoIter::F64(it) => it.next().map(Into::into),
312            ArrayValueIntoIter::String(it) => it.next().map(Into::into),
313            ArrayValueIntoIter::Array(it) => it.next().map(Into::into),
314        }
315    }
316}
317
318pub enum ArrayValueIterCloned<'a> {
319    Sum(std::slice::Iter<'a, SumValue>),
320    Product(std::slice::Iter<'a, ProductValue>),
321    Bool(std::slice::Iter<'a, bool>),
322    I8(std::slice::Iter<'a, i8>),
323    U8(std::slice::Iter<'a, u8>),
324    I16(std::slice::Iter<'a, i16>),
325    U16(std::slice::Iter<'a, u16>),
326    I32(std::slice::Iter<'a, i32>),
327    U32(std::slice::Iter<'a, u32>),
328    I64(std::slice::Iter<'a, i64>),
329    U64(std::slice::Iter<'a, u64>),
330    I128(std::slice::Iter<'a, i128>),
331    U128(std::slice::Iter<'a, u128>),
332    I256(std::slice::Iter<'a, i256>),
333    U256(std::slice::Iter<'a, u256>),
334    F32(std::slice::Iter<'a, F32>),
335    F64(std::slice::Iter<'a, F64>),
336    String(std::slice::Iter<'a, Box<str>>),
337    Array(std::slice::Iter<'a, ArrayValue>),
338}
339
340impl Iterator for ArrayValueIterCloned<'_> {
341    type Item = AlgebraicValue;
342
343    fn next(&mut self) -> Option<Self::Item> {
344        match self {
345            ArrayValueIterCloned::Sum(it) => it.next().cloned().map(Into::into),
346            ArrayValueIterCloned::Product(it) => it.next().cloned().map(Into::into),
347            ArrayValueIterCloned::Bool(it) => it.next().cloned().map(Into::into),
348            ArrayValueIterCloned::I8(it) => it.next().cloned().map(Into::into),
349            ArrayValueIterCloned::U8(it) => it.next().cloned().map(Into::into),
350            ArrayValueIterCloned::I16(it) => it.next().cloned().map(Into::into),
351            ArrayValueIterCloned::U16(it) => it.next().cloned().map(Into::into),
352            ArrayValueIterCloned::I32(it) => it.next().cloned().map(Into::into),
353            ArrayValueIterCloned::U32(it) => it.next().cloned().map(Into::into),
354            ArrayValueIterCloned::I64(it) => it.next().cloned().map(Into::into),
355            ArrayValueIterCloned::U64(it) => it.next().cloned().map(Into::into),
356            ArrayValueIterCloned::I128(it) => it.next().cloned().map(Into::into),
357            ArrayValueIterCloned::U128(it) => it.next().cloned().map(Into::into),
358            ArrayValueIterCloned::I256(it) => it.next().cloned().map(Into::into),
359            ArrayValueIterCloned::U256(it) => it.next().cloned().map(Into::into),
360            ArrayValueIterCloned::F32(it) => it.next().cloned().map(Into::into),
361            ArrayValueIterCloned::F64(it) => it.next().cloned().map(Into::into),
362            ArrayValueIterCloned::String(it) => it.next().cloned().map(Into::into),
363            ArrayValueIterCloned::Array(it) => it.next().cloned().map(Into::into),
364        }
365    }
366}