use alloc::borrow::Cow;
use serde::{Deserialize, Serialize};
use crate::models::amount::XRPAmount;
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct State<'a> {
pub amendment_blocked: Option<bool>,
pub build_version: Cow<'a, str>,
pub complete_ledgers: Option<Cow<'a, str>>,
pub closed_ledger: Option<ValidatedLedger<'a>>,
pub io_latency_ms: Option<u32>,
pub jq_trans_overflow: Option<Cow<'a, str>>,
pub last_close: Option<LastClose>,
pub load_base: Option<u32>,
pub load_factor: Option<u32>,
pub load_factor_fee_escalation: Option<u32>,
pub load_factor_fee_queue: Option<u32>,
pub load_factor_fee_reference: Option<u32>,
pub load_factor_server: Option<u32>,
pub peer_disconnects: Option<Cow<'a, str>>,
pub peer_disconnects_resources: Option<Cow<'a, str>>,
pub peers: Option<u32>,
pub pubkey_node: Option<Cow<'a, str>>,
pub server_state: Option<Cow<'a, str>>,
pub server_state_duration_us: Option<Cow<'a, str>>,
pub state_accounting: Option<StateAccounting>,
pub time: Option<Cow<'a, str>>,
pub uptime: Option<u64>,
pub validated_ledger: Option<ValidatedLedger<'a>>,
pub validation_quorum: Option<u32>,
pub ports: Option<Cow<'a, [PortDescriptor<'a>]>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct LastClose {
pub converge_time: u32,
pub proposers: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct StateAccountingEntry {
pub duration_us: Cow<'static, str>,
pub transitions: Cow<'static, str>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct StateAccounting {
pub connected: Option<StateAccountingEntry>,
pub disconnected: Option<StateAccountingEntry>,
pub full: Option<StateAccountingEntry>,
pub syncing: Option<StateAccountingEntry>,
pub tracking: Option<StateAccountingEntry>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PortDescriptor<'a> {
pub port: Cow<'a, str>,
pub protocol: Cow<'a, [Cow<'a, str>]>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct ValidatedLedger<'a> {
pub base_fee: XRPAmount<'a>,
pub close_time: u32,
pub hash: Cow<'a, str>,
pub reserve_base: XRPAmount<'a>,
pub reserve_inc: XRPAmount<'a>,
pub seq: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct ServerState<'a> {
pub state: State<'a>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_server_state_deserialize() {
let json = r#"{
"state": {
"build_version": "1.7.2",
"complete_ledgers": "65844785-65887184",
"io_latency_ms": 3,
"jq_trans_overflow": "580",
"last_close": {
"converge_time": 3012,
"proposers": 41
},
"load_base": 256,
"load_factor": 134022,
"load_factor_fee_escalation": 134022,
"load_factor_fee_queue": 256,
"load_factor_fee_reference": 256,
"load_factor_server": 256,
"peer_disconnects": "792367",
"peer_disconnects_resources": "7273",
"peers": 72,
"pubkey_node": "n9LNvsFiYfFf8va6pma2PHGJKVLSyZweN1iBAkJQSeHw4GjM8gvN",
"server_state": "full",
"server_state_duration_us": "422128665555",
"state_accounting": {
"connected": {
"duration_us": "172799714",
"transitions": "1"
},
"disconnected": {
"duration_us": "309059",
"transitions": "1"
},
"full": {
"duration_us": "6020429212246",
"transitions": "143"
},
"syncing": {
"duration_us": "413813232",
"transitions": "152"
},
"tracking": {
"duration_us": "266553605",
"transitions": "152"
}
},
"time": "2021-Aug-24 20:43:43.043406 UTC",
"uptime": 6021282,
"validated_ledger": {
"base_fee": 10,
"close_time": 683153020,
"hash": "ABEF3D24015E8B6B7184B4ABCEDC0E0E3AA4F0677FAB91C40B1E500707C1F3E5",
"reserve_base": 20000000,
"reserve_inc": 5000000,
"seq": 65887184
},
"validation_quorum": 33
},
"status": "success"
}"#;
let result: ServerState = serde_json::from_str(json).unwrap();
assert_eq!(result.state.build_version, "1.7.2");
assert_eq!(
result.state.complete_ledgers,
Some("65844785-65887184".into())
);
assert_eq!(result.state.io_latency_ms, Some(3));
assert_eq!(result.state.jq_trans_overflow, Some("580".into()));
assert_eq!(
result.state.last_close.as_ref().unwrap().converge_time,
3012
);
assert_eq!(result.state.last_close.as_ref().unwrap().proposers, 41);
assert_eq!(result.state.load_base, Some(256));
assert_eq!(result.state.load_factor, Some(134022));
assert_eq!(result.state.peers, Some(72));
assert_eq!(result.state.server_state, Some("full".into()));
let validated_ledger = result.state.validated_ledger.unwrap();
assert_eq!(validated_ledger.base_fee, XRPAmount::from("10"));
assert_eq!(validated_ledger.close_time, 683153020);
assert_eq!(
validated_ledger.hash,
"ABEF3D24015E8B6B7184B4ABCEDC0E0E3AA4F0677FAB91C40B1E500707C1F3E5"
);
assert_eq!(validated_ledger.seq, 65887184);
let state_accounting = result.state.state_accounting.unwrap();
assert_eq!(state_accounting.full.as_ref().unwrap().transitions, "143");
assert_eq!(
state_accounting.syncing.as_ref().unwrap().transitions,
"152"
);
}
}