use core::fmt::Debug;
use core::hash::Hash;
use commit_verify::{CommitEncode, Conceal};
use strict_encoding::{StrictDecode, StrictDumb, StrictEncode};
use crate::{
ConcealedAttach, ConcealedData, ConcealedValue, RevealedAttach, RevealedData, RevealedValue,
LIB_NAME_RGB,
};
pub trait ConfidentialState:
Debug + Hash + StrictDumb + StrictEncode + StrictDecode + CommitEncode + Eq + Copy
{
fn state_type(&self) -> StateType;
fn state_commitment(&self) -> StateCommitment;
}
pub trait ExposedState:
Debug
+ StrictDumb
+ StrictEncode
+ StrictDecode
+ Conceal<Concealed = Self::Confidential>
+ CommitEncode
+ Eq
+ Ord
+ Clone
{
type Confidential: ConfidentialState;
fn state_type(&self) -> StateType;
fn state_data(&self) -> StateData;
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
#[display(lowercase)]
pub enum StateType {
Void,
Fungible,
Structured,
Attachment,
}
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB, tags = custom)]
#[derive(CommitEncode)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub enum StateData {
#[strict_type(tag = 0x00, dumb)]
Void,
#[strict_type(tag = 0x01)]
Fungible(RevealedValue),
#[strict_type(tag = 0x02)]
Structured(RevealedData),
#[strict_type(tag = 0xFF)]
Attachment(RevealedAttach),
}
impl ExposedState for StateData {
type Confidential = StateCommitment;
fn state_type(&self) -> StateType {
match self {
StateData::Void => StateType::Void,
StateData::Fungible(_) => StateType::Fungible,
StateData::Structured(_) => StateType::Structured,
StateData::Attachment(_) => StateType::Attachment,
}
}
fn state_data(&self) -> StateData { self.clone() }
}
impl Conceal for StateData {
type Concealed = StateCommitment;
fn conceal(&self) -> Self::Concealed {
match self {
StateData::Void => StateCommitment::Void,
StateData::Fungible(value) => StateCommitment::Fungible(value.conceal()),
StateData::Structured(data) => StateCommitment::Structured(data.conceal()),
StateData::Attachment(attach) => StateCommitment::Attachment(attach.conceal()),
}
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = LIB_NAME_RGB, tags = custom)]
#[derive(CommitEncode)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase")
)]
pub enum StateCommitment {
#[strict_type(tag = 0x00, dumb)]
Void,
#[strict_type(tag = 0x01)]
Fungible(ConcealedValue),
#[strict_type(tag = 0x02)]
Structured(ConcealedData),
#[strict_type(tag = 0xFF)]
Attachment(ConcealedAttach),
}
impl ConfidentialState for StateCommitment {
fn state_type(&self) -> StateType {
match self {
StateCommitment::Void => StateType::Void,
StateCommitment::Fungible(_) => StateType::Fungible,
StateCommitment::Structured(_) => StateType::Structured,
StateCommitment::Attachment(_) => StateType::Attachment,
}
}
fn state_commitment(&self) -> StateCommitment { *self }
}