diff --git a/src/rtr/cache/model.rs b/src/rtr/cache/model.rs index e8b631e..0f5134b 100644 --- a/src/rtr/cache/model.rs +++ b/src/rtr/cache/model.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::sync::{Arc, OnceLock}; use std::time::{Duration, Instant}; -use chrono::{DateTime, NaiveDateTime, Utc}; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -57,9 +57,8 @@ impl<'de> Deserialize<'de> for DualTime { D: serde::Deserializer<'de>, { let millis = i64::deserialize(deserializer)?; - let naive = NaiveDateTime::from_timestamp_millis(millis) + let utc = DateTime::from_timestamp_millis(millis) .ok_or_else(|| serde::de::Error::custom("invalid timestamp"))?; - let utc = DateTime::::from_utc(naive, Utc); Ok(Self { instant: Instant::now(), diff --git a/src/rtr/payload.rs b/src/rtr/payload.rs index b673b5e..cfcbb9d 100644 --- a/src/rtr/payload.rs +++ b/src/rtr/payload.rs @@ -7,14 +7,6 @@ use std::time::Duration; use x509_parser::prelude::FromDer; use x509_parser::x509::SubjectPublicKeyInfo; -#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] -enum PayloadPduType { - Ipv4Prefix = 4, - Ipv6Prefix = 6, - RouterKey = 9, - Aspa = 11, -} - #[derive( Clone, Copy, Debug, Default, Eq, Hash, PartialEq, Ord, PartialOrd, Serialize, Deserialize, )] diff --git a/src/source/ccr.rs b/src/source/ccr.rs index 7ec33bc..a57661e 100644 --- a/src/source/ccr.rs +++ b/src/source/ccr.rs @@ -49,13 +49,15 @@ pub fn load_ccr_payloads_from_file_with_options( pub fn find_latest_ccr_file(dir: impl AsRef) -> Result { let dir = dir.as_ref(); + let latest_date_dir = find_latest_subdir_by_name(dir)?; + let scan_dir = latest_date_dir.as_deref().unwrap_or(dir); let mut latest: Option = None; - for entry in fs::read_dir(dir) - .with_context(|| format!("failed to read CCR directory: {}", dir.display()))? + for entry in fs::read_dir(scan_dir) + .with_context(|| format!("failed to read CCR directory: {}", scan_dir.display()))? { - let entry = - entry.with_context(|| format!("failed to iterate CCR directory: {}", dir.display()))?; + let entry = entry + .with_context(|| format!("failed to iterate CCR directory: {}", scan_dir.display()))?; let path = entry.path(); if !path.is_file() { continue; @@ -72,7 +74,7 @@ pub fn find_latest_ccr_file(dir: impl AsRef) -> Result { } } - latest.ok_or_else(|| anyhow!("no .ccr files found in {}", dir.display())) + latest.ok_or_else(|| anyhow!("no .ccr files found in {}", scan_dir.display())) } pub fn snapshot_to_payloads(snapshot: &ParsedCcrSnapshot) -> Result> { @@ -353,3 +355,27 @@ fn file_name_key(path: &Path) -> String { .map(|name| name.to_ascii_lowercase()) .unwrap_or_default() } + +fn find_latest_subdir_by_name(dir: &Path) -> Result> { + let mut latest: Option = None; + + for entry in + fs::read_dir(dir).with_context(|| format!("failed to read CCR directory: {}", dir.display()))? + { + let entry = + entry.with_context(|| format!("failed to iterate CCR directory: {}", dir.display()))?; + let path = entry.path(); + if !path.is_dir() { + continue; + } + + if latest + .as_ref() + .is_none_or(|current| file_name_key(&path) > file_name_key(current)) + { + latest = Some(path); + } + } + + Ok(latest) +} diff --git a/tests/test_ccr.rs b/tests/test_ccr.rs index 8251999..27b5381 100644 --- a/tests/test_ccr.rs +++ b/tests/test_ccr.rs @@ -45,6 +45,23 @@ fn find_latest_ccr_file_picks_latest_name() { assert_eq!(latest, newer); } +#[test] +fn find_latest_ccr_file_picks_latest_date_dir_first() { + let root = tempdir().expect("create temp root dir"); + let older_dir = root.path().join("20260401"); + let newer_dir = root.path().join("20260402"); + fs::create_dir_all(&older_dir).expect("create older date dir"); + fs::create_dir_all(&newer_dir).expect("create newer date dir"); + + let older = older_dir.join("20260401T000001Z-a.ccr"); + let newer = newer_dir.join("20260402T000001Z-b.ccr"); + fs::write(&older, b"older").expect("write older ccr"); + fs::write(&newer, b"newer").expect("write newer ccr"); + + let latest = find_latest_ccr_file(root.path()).expect("find latest ccr"); + assert_eq!(latest, newer); +} + #[test] fn snapshot_to_payloads_with_options_skips_invalid_aspa_when_not_strict() { let snapshot = ParsedCcrSnapshot {