use aluvm::library::LibSite;
use amplify::confinement::{TinyOrdMap, TinyOrdSet};
use amplify::Wrapper;
use strict_encoding::DefaultBasedStrictDumb;
use super::{GlobalStateType, Occurrences, TransitionType};
use crate::schema::schema::MetaType;
use crate::LIB_NAME_RGB_COMMIT;
#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From, Display)]
#[wrapper(FromStr, LowerHex, UpperHex)]
#[display(inner)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB_COMMIT)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct AssignmentType(u16);
impl AssignmentType {
pub const fn with(ty: u16) -> Self { Self(ty) }
#[inline]
pub fn to_le_bytes(&self) -> [u8; 2] { self.0.to_le_bytes() }
pub const ASSET: Self = AssignmentType(4000);
pub fn is_asset(self) -> bool { self == Self::ASSET }
}
pub type MetaSchema = TinyOrdSet<MetaType>;
pub type GlobalSchema = TinyOrdMap<GlobalStateType, Occurrences>;
pub type InputsSchema = TinyOrdMap<AssignmentType, Occurrences>;
pub type AssignmentsSchema = TinyOrdMap<AssignmentType, Occurrences>;
#[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("transition #{0}")]
StateTransition(TransitionType),
}
impl OpFullType {
pub fn subtype(self) -> u16 {
match self {
OpFullType::Genesis => 0,
OpFullType::StateTransition(ty) => ty.to_inner(),
}
}
pub fn is_transition(self) -> bool { matches!(self, Self::StateTransition(_)) }
}
pub trait OpSchema {
fn metadata(&self) -> &MetaSchema;
fn globals(&self) -> &GlobalSchema;
fn inputs(&self) -> Option<&InputsSchema>;
fn assignments(&self) -> &AssignmentsSchema;
}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB_COMMIT)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct GenesisSchema {
pub metadata: MetaSchema,
pub globals: GlobalSchema,
pub assignments: AssignmentsSchema,
pub validator: Option<LibSite>,
}
impl DefaultBasedStrictDumb for GenesisSchema {}
#[derive(Clone, PartialEq, Eq, Debug, Default)]
#[derive(StrictType, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB_COMMIT)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub struct TransitionSchema {
pub metadata: MetaSchema,
pub globals: GlobalSchema,
pub inputs: InputsSchema,
pub assignments: AssignmentsSchema,
pub validator: Option<LibSite>,
}
impl DefaultBasedStrictDumb for TransitionSchema {}
impl OpSchema for GenesisSchema {
#[inline]
fn metadata(&self) -> &MetaSchema { &self.metadata }
#[inline]
fn globals(&self) -> &GlobalSchema { &self.globals }
#[inline]
fn inputs(&self) -> Option<&InputsSchema> { None }
#[inline]
fn assignments(&self) -> &AssignmentsSchema { &self.assignments }
}
impl OpSchema for TransitionSchema {
#[inline]
fn metadata(&self) -> &MetaSchema { &self.metadata }
#[inline]
fn globals(&self) -> &GlobalSchema { &self.globals }
#[inline]
fn inputs(&self) -> Option<&AssignmentsSchema> { Some(&self.inputs) }
#[inline]
fn assignments(&self) -> &AssignmentsSchema { &self.assignments }
}