use strict_encoding::{StrictDecode, StrictDumb, StrictEncode};
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
#[strict_type(lib = dbc::LIB_NAME_BPCORE, tags = custom, dumb = Self::Bitcoin(strict_dumb!()))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(rename_all = "camelCase"))]
pub enum Bp<T>
where T: StrictDumb + StrictEncode + StrictDecode
{
#[strict_type(tag = 0x00)]
Bitcoin(T),
#[strict_type(tag = 0x01)]
Liquid(T),
}
impl<T: StrictDumb + StrictEncode + StrictDecode> Bp<T> {
pub fn is_bitcoin(&self) -> bool { matches!(self, Bp::Bitcoin(_)) }
pub fn is_liquid(&self) -> bool { matches!(self, Bp::Liquid(_)) }
pub fn as_bitcoin(&self) -> Option<&T> {
match self {
Bp::Bitcoin(t) => Some(t),
Bp::Liquid(_) => None,
}
}
pub fn as_liquid(&self) -> Option<&T> {
match self {
Bp::Bitcoin(_) => None,
Bp::Liquid(t) => Some(t),
}
}
pub fn into_bitcoin(self) -> Option<T> {
match self {
Bp::Bitcoin(t) => Some(t),
Bp::Liquid(_) => None,
}
}
pub fn into_liquid(self) -> Option<T> {
match self {
Bp::Bitcoin(_) => None,
Bp::Liquid(t) => Some(t),
}
}
pub fn map<U: StrictDumb + StrictEncode + StrictDecode>(self, f: impl FnOnce(T) -> U) -> Bp<U> {
match self {
Bp::Bitcoin(t) => Bp::Bitcoin(f(t)),
Bp::Liquid(t) => Bp::Liquid(f(t)),
}
}
pub fn try_map<U: StrictDumb + StrictEncode + StrictDecode, E>(
self,
f: impl FnOnce(T) -> Result<U, E>,
) -> Result<Bp<U>, E> {
match self {
Bp::Bitcoin(t) => f(t).map(Bp::Bitcoin),
Bp::Liquid(t) => f(t).map(Bp::Liquid),
}
}
pub fn maybe_map<U: StrictDumb + StrictEncode + StrictDecode>(
self,
f: impl FnOnce(T) -> Option<U>,
) -> Option<Bp<U>> {
match self {
Bp::Bitcoin(t) => f(t).map(Bp::Bitcoin),
Bp::Liquid(t) => f(t).map(Bp::Liquid),
}
}
}