use std::{
convert::TryFrom,
fmt,
fmt::{Display, Error, Formatter},
};
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub use crate::tx_id::TxId;
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum LegacyTransactionStatus {
Completed = 0,
Broadcast = 1,
MinedUnconfirmed = 2,
Imported = 3,
#[default]
Pending = 4,
Coinbase = 5,
MinedConfirmed = 6,
Rejected = 7,
OneSidedUnconfirmed = 8,
OneSidedConfirmed = 9,
Queued = 10,
CoinbaseUnconfirmed = 11,
CoinbaseConfirmed = 12,
CoinbaseNotInBlockChain = 13,
}
impl LegacyTransactionStatus {
pub fn is_imported_from_chain(&self) -> bool {
matches!(
self,
LegacyTransactionStatus::Imported |
LegacyTransactionStatus::OneSidedUnconfirmed |
LegacyTransactionStatus::OneSidedConfirmed
)
}
pub fn is_coinbase(&self) -> bool {
matches!(
self,
LegacyTransactionStatus::CoinbaseUnconfirmed |
LegacyTransactionStatus::CoinbaseConfirmed |
LegacyTransactionStatus::CoinbaseNotInBlockChain
)
}
pub fn is_pending(&self) -> bool {
matches!(self, LegacyTransactionStatus::Pending)
}
pub fn is_completed(&self) -> bool {
matches!(self, LegacyTransactionStatus::Completed)
}
pub fn is_confirmed(&self) -> bool {
matches!(
self,
LegacyTransactionStatus::OneSidedConfirmed |
LegacyTransactionStatus::CoinbaseConfirmed |
LegacyTransactionStatus::MinedConfirmed
)
}
pub fn is_mined(&self) -> bool {
matches!(
self,
LegacyTransactionStatus::MinedUnconfirmed |
LegacyTransactionStatus::MinedConfirmed |
LegacyTransactionStatus::CoinbaseConfirmed |
LegacyTransactionStatus::CoinbaseUnconfirmed |
LegacyTransactionStatus::OneSidedConfirmed |
LegacyTransactionStatus::OneSidedUnconfirmed
)
}
pub fn mined_confirm(&self) -> Self {
match self {
LegacyTransactionStatus::Completed |
LegacyTransactionStatus::Broadcast |
LegacyTransactionStatus::Pending |
LegacyTransactionStatus::Coinbase |
LegacyTransactionStatus::Rejected |
LegacyTransactionStatus::Queued |
LegacyTransactionStatus::MinedUnconfirmed |
LegacyTransactionStatus::MinedConfirmed => LegacyTransactionStatus::MinedConfirmed,
LegacyTransactionStatus::Imported |
LegacyTransactionStatus::OneSidedUnconfirmed |
LegacyTransactionStatus::OneSidedConfirmed => LegacyTransactionStatus::OneSidedConfirmed,
LegacyTransactionStatus::CoinbaseNotInBlockChain |
LegacyTransactionStatus::CoinbaseConfirmed |
LegacyTransactionStatus::CoinbaseUnconfirmed => LegacyTransactionStatus::CoinbaseConfirmed,
}
}
pub fn mined_unconfirm(&self) -> Self {
match self {
LegacyTransactionStatus::Completed |
LegacyTransactionStatus::Broadcast |
LegacyTransactionStatus::Pending |
LegacyTransactionStatus::Coinbase |
LegacyTransactionStatus::Rejected |
LegacyTransactionStatus::Queued |
LegacyTransactionStatus::MinedUnconfirmed |
LegacyTransactionStatus::MinedConfirmed => LegacyTransactionStatus::MinedUnconfirmed,
LegacyTransactionStatus::Imported |
LegacyTransactionStatus::OneSidedUnconfirmed |
LegacyTransactionStatus::OneSidedConfirmed => LegacyTransactionStatus::OneSidedUnconfirmed,
LegacyTransactionStatus::CoinbaseConfirmed |
LegacyTransactionStatus::CoinbaseUnconfirmed |
LegacyTransactionStatus::CoinbaseNotInBlockChain => LegacyTransactionStatus::CoinbaseUnconfirmed,
}
}
}
#[derive(Debug, Error)]
#[error("Invalid TransactionStatus: {code}")]
pub struct TransactionConversionError {
pub code: i32,
}
impl TryFrom<i32> for LegacyTransactionStatus {
type Error = TransactionConversionError;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(LegacyTransactionStatus::Completed),
1 => Ok(LegacyTransactionStatus::Broadcast),
2 => Ok(LegacyTransactionStatus::MinedUnconfirmed),
3 => Ok(LegacyTransactionStatus::Imported),
4 => Ok(LegacyTransactionStatus::Pending),
5 => Ok(LegacyTransactionStatus::Coinbase),
6 => Ok(LegacyTransactionStatus::MinedConfirmed),
7 => Ok(LegacyTransactionStatus::Rejected),
8 => Ok(LegacyTransactionStatus::OneSidedUnconfirmed),
9 => Ok(LegacyTransactionStatus::OneSidedConfirmed),
10 => Ok(LegacyTransactionStatus::Queued),
11 => Ok(LegacyTransactionStatus::CoinbaseUnconfirmed),
12 => Ok(LegacyTransactionStatus::CoinbaseConfirmed),
13 => Ok(LegacyTransactionStatus::CoinbaseNotInBlockChain),
code => Err(TransactionConversionError { code }),
}
}
}
impl Display for LegacyTransactionStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self {
LegacyTransactionStatus::Completed => write!(f, "Completed"),
LegacyTransactionStatus::Broadcast => write!(f, "Broadcast"),
LegacyTransactionStatus::MinedUnconfirmed => write!(f, "Mined Unconfirmed"),
LegacyTransactionStatus::MinedConfirmed => write!(f, "Mined Confirmed"),
LegacyTransactionStatus::Imported => write!(f, "Imported"),
LegacyTransactionStatus::Pending => write!(f, "Pending"),
LegacyTransactionStatus::Coinbase => write!(f, "Coinbase"),
LegacyTransactionStatus::Rejected => write!(f, "Rejected"),
LegacyTransactionStatus::OneSidedUnconfirmed => write!(f, "One-Sided Unconfirmed"),
LegacyTransactionStatus::OneSidedConfirmed => write!(f, "One-Sided Confirmed"),
LegacyTransactionStatus::CoinbaseUnconfirmed => write!(f, "Coinbase Unconfirmed"),
LegacyTransactionStatus::CoinbaseConfirmed => write!(f, "Coinbase Confirmed"),
LegacyTransactionStatus::CoinbaseNotInBlockChain => write!(f, "Coinbase not mined"),
LegacyTransactionStatus::Queued => write!(f, "Queued"),
}
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum TransactionStatus {
#[default]
Completed = 0,
Broadcast = 1,
MinedUnconfirmed = 2,
MinedConfirmed = 3,
Rejected = 4,
}
impl TransactionStatus {
pub fn is_confirmed(&self) -> bool {
matches!(self, TransactionStatus::MinedConfirmed)
}
pub fn is_mined(&self) -> bool {
matches!(
self,
TransactionStatus::MinedUnconfirmed | TransactionStatus::MinedConfirmed
)
}
}
impl TryFrom<i32> for TransactionStatus {
type Error = TransactionConversionError;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(TransactionStatus::Completed),
1 => Ok(TransactionStatus::Broadcast),
2 => Ok(TransactionStatus::MinedUnconfirmed),
3 => Ok(TransactionStatus::MinedConfirmed),
4 => Ok(TransactionStatus::Rejected),
code => Err(TransactionConversionError { code }),
}
}
}
impl Display for TransactionStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self {
TransactionStatus::Completed => write!(f, "Completed"),
TransactionStatus::Broadcast => write!(f, "Broadcast"),
TransactionStatus::MinedUnconfirmed => write!(f, "Mined Unconfirmed"),
TransactionStatus::MinedConfirmed => write!(f, "Mined Confirmed"),
TransactionStatus::Rejected => write!(f, "Rejected"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum LegacyImportStatus {
Broadcast,
Imported,
OneSidedUnconfirmed,
OneSidedConfirmed,
CoinbaseUnconfirmed,
CoinbaseConfirmed,
}
impl TryFrom<LegacyImportStatus> for LegacyTransactionStatus {
type Error = TransactionConversionError;
fn try_from(value: LegacyImportStatus) -> Result<Self, Self::Error> {
match value {
LegacyImportStatus::Broadcast => Ok(LegacyTransactionStatus::Broadcast),
LegacyImportStatus::Imported => Ok(LegacyTransactionStatus::Imported),
LegacyImportStatus::OneSidedUnconfirmed => Ok(LegacyTransactionStatus::OneSidedUnconfirmed),
LegacyImportStatus::OneSidedConfirmed => Ok(LegacyTransactionStatus::OneSidedConfirmed),
LegacyImportStatus::CoinbaseUnconfirmed => Ok(LegacyTransactionStatus::CoinbaseUnconfirmed),
LegacyImportStatus::CoinbaseConfirmed => Ok(LegacyTransactionStatus::CoinbaseConfirmed),
}
}
}
impl TryFrom<LegacyTransactionStatus> for LegacyImportStatus {
type Error = TransactionConversionError;
fn try_from(value: LegacyTransactionStatus) -> Result<Self, Self::Error> {
match value {
LegacyTransactionStatus::Broadcast => Ok(LegacyImportStatus::Broadcast),
LegacyTransactionStatus::Imported => Ok(LegacyImportStatus::Imported),
LegacyTransactionStatus::OneSidedUnconfirmed => Ok(LegacyImportStatus::OneSidedUnconfirmed),
LegacyTransactionStatus::OneSidedConfirmed => Ok(LegacyImportStatus::OneSidedConfirmed),
LegacyTransactionStatus::CoinbaseUnconfirmed => Ok(LegacyImportStatus::CoinbaseUnconfirmed),
LegacyTransactionStatus::CoinbaseConfirmed => Ok(LegacyImportStatus::CoinbaseConfirmed),
_ => Err(TransactionConversionError { code: i32::MAX }),
}
}
}
impl fmt::Display for LegacyImportStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
LegacyImportStatus::Broadcast => write!(f, "Broadcast"),
LegacyImportStatus::Imported => write!(f, "Imported"),
LegacyImportStatus::OneSidedUnconfirmed => write!(f, "OneSidedUnconfirmed"),
LegacyImportStatus::OneSidedConfirmed => write!(f, "OneSidedConfirmed"),
LegacyImportStatus::CoinbaseUnconfirmed => write!(f, "CoinbaseUnconfirmed"),
LegacyImportStatus::CoinbaseConfirmed => write!(f, "CoinbaseConfirmed"),
}
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum TransactionDirection {
Inbound,
Outbound,
Unknown,
}
impl TransactionDirection {
pub fn is_outbound(&self) -> bool {
matches!(self, TransactionDirection::Outbound)
}
}
#[derive(Debug, Error)]
#[error("Invalid TransactionDirection: {code}")]
pub struct TransactionDirectionError {
pub code: i32,
}
impl TryFrom<i32> for TransactionDirection {
type Error = TransactionDirectionError;
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(TransactionDirection::Inbound),
1 => Ok(TransactionDirection::Outbound),
2 => Ok(TransactionDirection::Unknown),
code => Err(TransactionDirectionError { code }),
}
}
}
impl Display for TransactionDirection {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self {
TransactionDirection::Inbound => write!(f, "Inbound"),
TransactionDirection::Outbound => write!(f, "Outbound"),
TransactionDirection::Unknown => write!(f, "Unknown"),
}
}
}