use { serde::Serialize, solana_cli_output::{QuietDisplay, VerboseDisplay}, std::fmt::{Display, Formatter, Result}, }; #[derive(Serialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct SlotInfo { pub total: usize, pub first: Option, pub last: Option, #[serde(skip_serializing_if = "Option::is_none")] pub num_after_last_root: Option, } #[derive(Serialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct SlotBounds<'a> { #[serde(skip_serializing_if = "Option::is_none")] pub all_slots: Option<&'a Vec>, pub slots: SlotInfo, pub roots: SlotInfo, } impl VerboseDisplay for SlotBounds<'_> {} impl QuietDisplay for SlotBounds<'_> {} impl Display for SlotBounds<'_> { fn fmt(&self, f: &mut Formatter) -> Result { if self.slots.total > 0 { let first = self.slots.first.unwrap(); let last = self.slots.last.unwrap(); if first != last { writeln!( f, "Ledger has data for {:?} slots {:?} to {:?}", self.slots.total, first, last )?; if let Some(all_slots) = self.all_slots { writeln!(f, "Non-empty slots: {all_slots:?}")?; } } else { writeln!(f, "Ledger has data for slot {first:?}")?; } if self.roots.total > 0 { let first_rooted = self.roots.first.unwrap_or_default(); let last_rooted = self.roots.last.unwrap_or_default(); let num_after_last_root = self.roots.num_after_last_root.unwrap_or_default(); writeln!( f, " with {:?} rooted slots from {:?} to {:?}", self.roots.total, first_rooted, last_rooted )?; writeln!(f, " and {num_after_last_root:?} slots past the last root")?; } else { writeln!(f, " with no rooted slots")?; } } else { writeln!(f, "Ledger is empty")?; } Ok(()) } }