use super::channel_closing_transaction::ChannelClosingTransaction;
use super::channel_opening_transaction::ChannelOpeningTransaction;
use super::deposit::Deposit;
use super::withdrawal::Withdrawal;
use crate::objects::currency_amount::CurrencyAmount;
use crate::objects::entity::Entity;
use crate::objects::transaction::Transaction;
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use std::vec::Vec;
pub trait OnChainTransaction: Transaction + Entity {
fn get_fees(&self) -> Option<CurrencyAmount>;
fn get_block_hash(&self) -> Option<String>;
fn get_block_height(&self) -> i64;
fn get_destination_addresses(&self) -> Vec<String>;
fn get_num_confirmations(&self) -> Option<i64>;
fn type_name(&self) -> &'static str;
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, Serialize)]
pub enum OnChainTransactionEnum {
ChannelClosingTransaction(ChannelClosingTransaction),
ChannelOpeningTransaction(ChannelOpeningTransaction),
Deposit(Deposit),
Withdrawal(Withdrawal),
}
impl<'de> Deserialize<'de> for OnChainTransactionEnum {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = Value::deserialize(deserializer)?;
if let Some(typename) = value.get("__typename").and_then(Value::as_str) {
match typename {
"ChannelClosingTransaction" => {
let obj = ChannelClosingTransaction::deserialize(value).map_err(|err| {
serde::de::Error::custom(format!("Serde JSON Error {}", err))
})?;
Ok(OnChainTransactionEnum::ChannelClosingTransaction(obj))
}
"ChannelOpeningTransaction" => {
let obj = ChannelOpeningTransaction::deserialize(value).map_err(|err| {
serde::de::Error::custom(format!("Serde JSON Error {}", err))
})?;
Ok(OnChainTransactionEnum::ChannelOpeningTransaction(obj))
}
"Deposit" => {
let obj = Deposit::deserialize(value).map_err(|err| {
serde::de::Error::custom(format!("Serde JSON Error {}", err))
})?;
Ok(OnChainTransactionEnum::Deposit(obj))
}
"Withdrawal" => {
let obj = Withdrawal::deserialize(value).map_err(|err| {
serde::de::Error::custom(format!("Serde JSON Error {}", err))
})?;
Ok(OnChainTransactionEnum::Withdrawal(obj))
}
_ => Err(serde::de::Error::custom("unknown typename")),
}
} else {
Err(serde::de::Error::custom(
"missing __typename field on OnChainTransaction",
))
}
}
}