use {
crate::models,
serde::{Deserialize, Serialize},
};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum TransactionStatus {
#[serde(rename = "SUBMITTED")]
Submitted,
#[serde(rename = "PENDING_AML_SCREENING")]
PendingAmlScreening,
#[serde(rename = "PENDING_ENRICHMENT")]
PendingEnrichment,
#[serde(rename = "PENDING_AUTHORIZATION")]
PendingAuthorization,
#[serde(rename = "QUEUED")]
Queued,
#[serde(rename = "PENDING_SIGNATURE")]
PendingSignature,
#[serde(rename = "PENDING_3RD_PARTY_MANUAL_APPROVAL")]
Pending3RdPartyManualApproval,
#[serde(rename = "PENDING_3RD_PARTY")]
Pending3RdParty,
#[serde(rename = "BROADCASTING")]
Broadcasting,
#[serde(rename = "COMPLETED")]
Completed,
#[serde(rename = "CONFIRMING")]
Confirming,
#[serde(rename = "CANCELLING")]
Cancelling,
#[serde(rename = "CANCELLED")]
Cancelled,
#[serde(rename = "BLOCKED")]
Blocked,
#[serde(rename = "REJECTED")]
Rejected,
#[serde(rename = "FAILED")]
Failed,
}
impl std::fmt::Display for TransactionStatus {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Submitted => write!(f, "SUBMITTED"),
Self::PendingAmlScreening => write!(f, "PENDING_AML_SCREENING"),
Self::PendingEnrichment => write!(f, "PENDING_ENRICHMENT"),
Self::PendingAuthorization => write!(f, "PENDING_AUTHORIZATION"),
Self::Queued => write!(f, "QUEUED"),
Self::PendingSignature => write!(f, "PENDING_SIGNATURE"),
Self::Pending3RdPartyManualApproval => write!(f, "PENDING_3RD_PARTY_MANUAL_APPROVAL"),
Self::Pending3RdParty => write!(f, "PENDING_3RD_PARTY"),
Self::Broadcasting => write!(f, "BROADCASTING"),
Self::Completed => write!(f, "COMPLETED"),
Self::Confirming => write!(f, "CONFIRMING"),
Self::Cancelling => write!(f, "CANCELLING"),
Self::Cancelled => write!(f, "CANCELLED"),
Self::Blocked => write!(f, "BLOCKED"),
Self::Rejected => write!(f, "REJECTED"),
Self::Failed => write!(f, "FAILED"),
}
}
}
impl TransactionStatus {
pub const fn is_terminal(&self) -> bool {
use TransactionStatus::{
Blocked,
Broadcasting,
Cancelled,
Cancelling,
Completed,
Confirming,
Failed,
Pending3RdParty,
Pending3RdPartyManualApproval,
PendingAmlScreening,
PendingAuthorization,
PendingEnrichment,
PendingSignature,
Queued,
Rejected,
Submitted,
};
match self {
Blocked | Cancelled | Cancelling | Completed | Failed | Rejected => true,
Submitted
| PendingAmlScreening
| PendingEnrichment
| PendingAuthorization
| Queued
| PendingSignature
| Pending3RdPartyManualApproval
| Pending3RdParty
| Broadcasting
| Confirming => false,
}
}
}
impl Default for TransactionStatus {
fn default() -> TransactionStatus {
Self::Submitted
}
}
#[cfg(test)]
mod tests {
use super::TransactionStatus;
const TERMINAL_STATUSES: [TransactionStatus; 6] = [
TransactionStatus::Blocked,
TransactionStatus::Cancelled,
TransactionStatus::Cancelling,
TransactionStatus::Completed,
TransactionStatus::Failed,
TransactionStatus::Rejected,
];
const IN_PROGRESS_STATUSES: [TransactionStatus; 10] = [
TransactionStatus::Submitted,
TransactionStatus::PendingAmlScreening,
TransactionStatus::PendingEnrichment,
TransactionStatus::PendingAuthorization,
TransactionStatus::Queued,
TransactionStatus::PendingSignature,
TransactionStatus::Pending3RdPartyManualApproval,
TransactionStatus::Pending3RdParty,
TransactionStatus::Broadcasting,
TransactionStatus::Confirming,
];
#[test]
fn terminal_statuses_are_terminal() {
for status in TERMINAL_STATUSES {
assert!(
status.is_terminal(),
"{status} should be terminal but is_terminal() returned false"
);
}
}
#[test]
fn in_progress_statuses_are_not_terminal() {
for status in IN_PROGRESS_STATUSES {
assert!(
!status.is_terminal(),
"{status} should NOT be terminal but is_terminal() returned true"
);
}
}
#[test]
fn confirming_is_not_terminal() {
assert!(
!TransactionStatus::Confirming.is_terminal(),
"Confirming means on-chain confirmations are pending — it is NOT a terminal state"
);
}
}