use amplify::confinement::{TinyOrdMap, TinyOrdSet};
use strict_types::SemId;
use super::{ExtensionType, GlobalStateType, Occurrences, TransitionType};
use crate::LIB_NAME_RGB;
pub type AssignmentType = u16;
pub type ValencyType = u16;
pub type GlobalSchema = TinyOrdMap<GlobalStateType, Occurrences>;
pub type ValencySchema = TinyOrdSet<ValencyType>;
pub type InputsSchema = TinyOrdMap<AssignmentType, Occurrences>;
pub type AssignmentsSchema = TinyOrdMap<AssignmentType, Occurrences>;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
#[repr(u8)]
pub enum OpType {
#[display("genesis")]
Genesis = 0,
#[display("extension")]
StateExtension = 1,
#[display("transition")]
StateTransition = 2,
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub enum OpFullType {
#[display("genesis")]
Genesis,
#[display("state transition #{0}")]
StateTransition(TransitionType),
#[display("state extension #{0}")]
StateExtension(ExtensionType),
}
impl OpFullType {
pub fn subtype(self) -> u16 {
match self {
OpFullType::Genesis => 0,
OpFullType::StateTransition(ty) => ty,
OpFullType::StateExtension(ty) => ty,
}
}
pub fn is_transition(self) -> bool { matches!(self, Self::StateTransition(_)) }
pub fn is_extension(self) -> bool { matches!(self, Self::StateExtension(_)) }
}
pub trait OpSchema {
fn op_type(&self) -> OpType;
fn metadata(&self) -> SemId;
fn globals(&self) -> &GlobalSchema;
fn inputs(&self) -> Option<&InputsSchema>;
fn redeems(&self) -> Option<&ValencySchema>;
fn assignments(&self) -> &AssignmentsSchema;
fn valencies(&self) -> &ValencySchema;
}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct GenesisSchema {
pub metadata: SemId,
pub globals: GlobalSchema,
pub assignments: AssignmentsSchema,
pub valencies: ValencySchema,
}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct ExtensionSchema {
pub metadata: SemId,
pub globals: GlobalSchema,
pub redeems: ValencySchema,
pub assignments: AssignmentsSchema,
pub valencies: ValencySchema,
}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct TransitionSchema {
pub metadata: SemId,
pub globals: GlobalSchema,
pub inputs: InputsSchema,
pub assignments: AssignmentsSchema,
pub valencies: ValencySchema,
}
impl OpSchema for GenesisSchema {
#[inline]
fn op_type(&self) -> OpType { OpType::Genesis }
#[inline]
fn metadata(&self) -> SemId { self.metadata }
#[inline]
fn globals(&self) -> &GlobalSchema { &self.globals }
#[inline]
fn inputs(&self) -> Option<&InputsSchema> { None }
#[inline]
fn redeems(&self) -> Option<&ValencySchema> { None }
#[inline]
fn assignments(&self) -> &AssignmentsSchema { &self.assignments }
#[inline]
fn valencies(&self) -> &ValencySchema { &self.valencies }
}
impl OpSchema for ExtensionSchema {
#[inline]
fn op_type(&self) -> OpType { OpType::StateExtension }
#[inline]
fn metadata(&self) -> SemId { self.metadata }
#[inline]
fn globals(&self) -> &GlobalSchema { &self.globals }
#[inline]
fn inputs(&self) -> Option<&InputsSchema> { None }
#[inline]
fn redeems(&self) -> Option<&ValencySchema> { Some(&self.redeems) }
#[inline]
fn assignments(&self) -> &AssignmentsSchema { &self.assignments }
#[inline]
fn valencies(&self) -> &ValencySchema { &self.valencies }
}
impl OpSchema for TransitionSchema {
#[inline]
fn op_type(&self) -> OpType { OpType::StateTransition }
#[inline]
fn metadata(&self) -> SemId { self.metadata }
#[inline]
fn globals(&self) -> &GlobalSchema { &self.globals }
#[inline]
fn inputs(&self) -> Option<&AssignmentsSchema> { Some(&self.inputs) }
#[inline]
fn redeems(&self) -> Option<&ValencySchema> { None }
#[inline]
fn assignments(&self) -> &AssignmentsSchema { &self.assignments }
#[inline]
fn valencies(&self) -> &ValencySchema { &self.valencies }
}