use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::str::FromStr;
use bitcoin::hashes::Hash as _;
use bitcoin::hex::HexToArrayError;
use bitcoin::{OutPoint as Outpoint, Txid};
use strict_encoding::{StrictDecode, StrictDumb, StrictEncode};
use strict_types::StrictType;
use crate::{dbc, Vout};
pub type CloseMethod = dbc::Method;
pub trait TxoSeal {
fn txid(&self) -> Option<Txid>;
fn vout(&self) -> Vout;
fn outpoint(&self) -> Option<Outpoint>;
fn txid_or(&self, default_txid: Txid) -> Txid;
fn outpoint_or(&self, default_txid: Txid) -> Outpoint;
}
pub trait SealTxid:
Copy
+ Eq
+ Ord
+ Hash
+ Debug
+ Display
+ FromStr<Err = HexToArrayError>
+ StrictDumb
+ StrictEncode
+ StrictDecode
+ From<Txid>
{
fn txid(&self) -> Option<Txid>;
fn txid_or(&self, default: Txid) -> Txid;
fn map_to_outpoint(&self, vout: impl Into<Vout>) -> Option<Outpoint>;
}
impl SealTxid for Txid {
fn txid(&self) -> Option<Txid> { Some(*self) }
fn txid_or(&self, _default: Txid) -> Txid { *self }
fn map_to_outpoint(&self, vout: impl Into<Vout>) -> Option<Outpoint> {
Some(Outpoint::new(*self, vout.into().into_u32()))
}
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, From)]
#[derive(StrictType, StrictEncode, StrictDecode, StrictDumb)]
#[strict_type(lib = dbc::LIB_NAME_BPCORE, tags = custom)]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(crate = "serde_crate", rename_all = "camelCase", untagged)
)]
pub enum TxPtr {
#[strict_type(dumb)]
#[display("~")]
#[strict_type(tag = 0x0)]
WitnessTx,
#[from]
#[display(inner)]
#[strict_type(tag = 0x1)]
Txid(Txid),
}
impl From<&Txid> for TxPtr {
#[inline]
fn from(txid: &Txid) -> Self { TxPtr::Txid(*txid) }
}
impl From<[u8; 32]> for TxPtr {
#[inline]
fn from(txid: [u8; 32]) -> Self { TxPtr::Txid(Txid::from_byte_array(txid)) }
}
impl SealTxid for TxPtr {
fn txid(&self) -> Option<Txid> {
match self {
TxPtr::WitnessTx => None,
TxPtr::Txid(txid) => Some(*txid),
}
}
fn txid_or(&self, default: Txid) -> Txid {
match self {
TxPtr::WitnessTx => default,
TxPtr::Txid(txid) => *txid,
}
}
fn map_to_outpoint(&self, vout: impl Into<Vout>) -> Option<Outpoint> {
self.txid()
.map(|txid| Outpoint::new(txid, vout.into().into_u32()))
}
}
impl FromStr for TxPtr {
type Err = HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"~" => Ok(TxPtr::WitnessTx),
other => Txid::from_str(other).map(Self::from),
}
}
}