use alloc::borrow::Cow;
use serde::{Deserialize, Serialize};
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Ledger<'a> {
pub ledger: LedgerInner<'a>,
pub ledger_hash: Cow<'a, str>,
pub ledger_index: u32,
pub validated: Option<bool>,
pub queue_data: Option<Cow<'a, [QueuedTransaction<'a>]>>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LedgerInner<'a> {
pub account_hash: Cow<'a, str>,
pub close_flags: u32,
pub close_time: u64,
pub close_time_human: Option<Cow<'a, str>>,
pub close_time_resolution: u32,
pub closed: bool,
pub ledger_hash: Cow<'a, str>,
pub ledger_index: Cow<'a, str>,
pub parent_close_time: u64,
pub parent_hash: Cow<'a, str>,
pub total_coins: Cow<'a, str>,
pub transaction_hash: Cow<'a, str>,
pub transactions: Option<Cow<'a, [Cow<'a, str>]>>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct QueuedTransaction<'a> {
pub account: Cow<'a, str>,
pub tx: TransactionInfo<'a>,
pub retries_remaining: u32,
pub preflight_result: Cow<'a, str>,
pub last_result: Option<Cow<'a, str>>,
pub auth_change: Option<bool>,
pub fee: Option<Cow<'a, str>>,
pub fee_level: Option<Cow<'a, str>>,
pub max_spend_drops: Option<Cow<'a, str>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum TransactionInfo<'a> {
Hash(Cow<'a, str>),
Binary { tx_blob: Cow<'a, str> },
Json(TransactionObject<'a>),
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct TransactionObject<'a> {
pub hash: Cow<'a, str>,
#[serde(flatten)]
pub other: serde_json::Value,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ledger_deserialize() {
let json = r#"{
"ledger": {
"account_hash": "B8B2C0C3F9E75E3AEE31D467B2544AB56244E618890BA58679707D6BFC0AF41D",
"close_flags": 0,
"close_time": 752188602,
"close_time_human": "2023-Nov-01 21:16:42.000000000 UTC",
"close_time_resolution": 10,
"closed": true,
"ledger_hash": "1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B",
"ledger_index": "83626901",
"parent_close_time": 752188601,
"parent_hash": "6B32CFC42B32C5FB90019AE17F701D96B499A4C8E148A002E18135A434A19D98",
"total_coins": "99988256314388830",
"transaction_hash": "21586C664DC47E12AF34F22EBF1DB55D23F8C98972542BAC0C39B1009CAC84D4"
},
"ledger_hash": "1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B",
"ledger_index": 83626901,
"validated": true
}"#;
let result: Ledger = serde_json::from_str(json).unwrap();
assert_eq!(
result.ledger_hash,
"1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B"
);
assert_eq!(result.ledger_index, 83626901);
assert_eq!(result.validated, Some(true));
let inner = result.ledger;
assert_eq!(
inner.account_hash,
"B8B2C0C3F9E75E3AEE31D467B2544AB56244E618890BA58679707D6BFC0AF41D"
);
assert_eq!(inner.close_flags, 0);
assert_eq!(inner.close_time, 752188602);
assert_eq!(
inner.close_time_human,
Some("2023-Nov-01 21:16:42.000000000 UTC".into())
);
assert_eq!(inner.close_time_resolution, 10);
assert!(inner.closed);
assert_eq!(
inner.ledger_hash,
"1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B"
);
assert_eq!(inner.ledger_index, "83626901");
assert_eq!(inner.parent_close_time, 752188601);
assert_eq!(
inner.parent_hash,
"6B32CFC42B32C5FB90019AE17F701D96B499A4C8E148A002E18135A434A19D98"
);
assert_eq!(inner.total_coins, "99988256314388830");
assert_eq!(
inner.transaction_hash,
"21586C664DC47E12AF34F22EBF1DB55D23F8C98972542BAC0C39B1009CAC84D4"
);
}
#[test]
fn test_ledger_serialize() {
let ledger = Ledger {
ledger: LedgerInner {
account_hash: "B8B2C0C3F9E75E3AEE31D467B2544AB56244E618890BA58679707D6BFC0AF41D"
.into(),
close_flags: 0,
close_time: 752188602,
close_time_human: Some("2023-Nov-01 21:16:42.000000000 UTC".into()),
close_time_resolution: 10,
closed: true,
ledger_hash: "1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B"
.into(),
ledger_index: "83626901".into(),
parent_close_time: 752188601,
parent_hash: "6B32CFC42B32C5FB90019AE17F701D96B499A4C8E148A002E18135A434A19D98"
.into(),
total_coins: "99988256314388830".into(),
transaction_hash:
"21586C664DC47E12AF34F22EBF1DB55D23F8C98972542BAC0C39B1009CAC84D4".into(),
transactions: None,
},
ledger_hash: "1BEECD5D21592EABDEF98D8E4BC038AD10B5700FF7E98011870DF5D6C2A2F39B".into(),
ledger_index: 83626901,
validated: Some(true),
queue_data: None,
};
let serialized = serde_json::to_string(&ledger).unwrap();
let deserialized: Ledger = serde_json::from_str(&serialized).unwrap();
assert_eq!(ledger, deserialized);
}
}