From 42985e5c725da0f8de3fd03b67cb63c254c13eb6 Mon Sep 17 00:00:00 2001 From: ygd58 Date: Wed, 1 Apr 2026 13:34:16 +0200 Subject: [PATCH] feat: make ValidityWindow generic with Display and datetime conversion - ValidityWindow now generic over bound type - Generic Display implementation for all bound types - to_datetime_window() converts block-id window to UTC datetime window - Backward compatible: default type param is BlockId Enables ValidityWindow> for human-readable display. Refs #421 --- indexer/service/protocol/Cargo.toml | 1 + indexer/service/protocol/src/lib.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/indexer/service/protocol/Cargo.toml b/indexer/service/protocol/Cargo.toml index 2ee61b74..6b7c41a5 100644 --- a/indexer/service/protocol/Cargo.toml +++ b/indexer/service/protocol/Cargo.toml @@ -8,6 +8,7 @@ license = { workspace = true } workspace = true [dependencies] +chrono = { workspace = true } nssa_core = { workspace = true, optional = true, features = ["host"] } nssa = { workspace = true, optional = true } common = { workspace = true, optional = true } diff --git a/indexer/service/protocol/src/lib.rs b/indexer/service/protocol/src/lib.rs index 59e936bf..b773b6ec 100644 --- a/indexer/service/protocol/src/lib.rs +++ b/indexer/service/protocol/src/lib.rs @@ -303,11 +303,12 @@ pub struct Nullifier( ); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] -pub struct ValidityWindow(pub (Option, Option)); +#[serde(transparent)] +pub struct ValidityWindow(pub (Option, Option)); -impl Display for ValidityWindow { +impl Display for ValidityWindow { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.0 { + match &self.0 { (Some(start), Some(end)) => write!(f, "[{start}, {end})"), (Some(start), None) => write!(f, "[{start}, \u{221e})"), (None, Some(end)) => write!(f, "(-\u{221e}, {end})"), @@ -316,6 +317,26 @@ impl Display for ValidityWindow { } } +impl ValidityWindow { + /// Convert to a UTC datetime window given a block-to-timestamp mapping. + pub fn to_datetime_window( + &self, + block_to_timestamp_ms: F, + ) -> ValidityWindow> + where + F: Fn(BlockId) -> Option, + { + let convert = |id: &BlockId| { + block_to_timestamp_ms(*id) + .and_then(|ms| chrono::DateTime::from_timestamp_millis(ms as i64)) + }; + ValidityWindow(( + self.0.0.as_ref().and_then(&convert), + self.0.1.as_ref().and_then(&convert), + )) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)] pub struct CommitmentSetDigest( #[serde(with = "base64::arr")]