Skip to main content

spacetimedb_sats/
sum_value.rs

1use crate::algebraic_value::AlgebraicValue;
2use crate::impl_deserialize;
3use crate::sum_type::SumType;
4
5/// A value of a sum type choosing a specific variant of the type.
6#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
7pub struct SumValue {
8    /// A tag representing the choice of one variant of the sum type's variants.
9    pub tag: u8,
10    /// Given a variant `Var(Ty)` in a sum type `{ Var(Ty), ... }`,
11    /// this provides the `value` for `Ty`.
12    pub value: Box<AlgebraicValue>,
13}
14
15impl crate::Value for SumValue {
16    type Type = SumType;
17}
18
19impl SumValue {
20    /// Returns a new `SumValue` with the given `tag` and `value`.
21    pub fn new(tag: u8, value: impl Into<AlgebraicValue>) -> Self {
22        let value = Box::from(value.into());
23        Self { tag, value }
24    }
25
26    /// Returns a new `SumValue` with the given `tag` and unit value.
27    pub fn new_simple(tag: u8) -> Self {
28        Self::new(tag, ())
29    }
30}
31
32/// The tag of a `SumValue`.
33/// Can be used to read out the tag of a sum value without reading the payload.
34#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
35#[repr(transparent)]
36pub struct SumTag(pub u8);
37
38impl_deserialize!([] SumTag, de => <_>::deserialize(de).map(SumTag));
39
40#[cfg(feature = "memory-usage")]
41impl spacetimedb_memory_usage::MemoryUsage for SumTag {}
42
43impl From<&u8> for &SumTag {
44    fn from(value: &u8) -> Self {
45        // SAFETY: `SumTag` is `repr(transparent)` of `u8`.
46        unsafe { core::mem::transmute(value) }
47    }
48}
49
50impl From<SumTag> for SumValue {
51    fn from(SumTag(tag): SumTag) -> Self {
52        SumValue::new_simple(tag)
53    }
54}