From 152cd3ab6386a008950e7f72217f763f6164811c Mon Sep 17 00:00:00 2001 From: ProofOfConcept Date: Tue, 3 Mar 2026 18:06:59 -0500 Subject: [PATCH] digest: inline label_dates closures into DigestLevel definitions Move weekly_label_dates and monthly_label_dates bodies into their DigestLevel const definitions as closures, matching the style already used by date_to_label. All per-level behavior is now co-located. Signed-off-by: Kent Overstreet --- src/digest.rs | 110 +++++++++++++++++++++++--------------------------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/src/digest.rs b/src/digest.rs index 7275e1a..3706e47 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -42,6 +42,19 @@ const DAILY: DigestLevel = DigestLevel { date_to_label: |date| Some(date.to_string()), }; +/// Week label and 7 dates (Mon-Sun) for the week containing `date`. +fn week_dates(date: &str) -> Result<(String, Vec), String> { + let nd = NaiveDate::parse_from_str(date, "%Y-%m-%d") + .map_err(|e| format!("bad date '{}': {}", date, e))?; + let iso = nd.iso_week(); + let week_label = format!("{}-W{:02}", iso.year(), iso.week()); + let monday = nd - Duration::days(nd.weekday().num_days_from_monday() as i64); + let dates = (0..7) + .map(|i| (monday + Duration::days(i)).format("%Y-%m-%d").to_string()) + .collect(); + Ok((week_label, dates)) +} + const WEEKLY: DigestLevel = DigestLevel { name: "weekly", title: "Weekly", @@ -49,7 +62,21 @@ const WEEKLY: DigestLevel = DigestLevel { input_title: "Daily digests", timeout: 300, child_name: Some("daily"), - label_dates: weekly_label_dates, + label_dates: |arg| { + if !arg.contains('W') { + return week_dates(arg); + } + let (y, w) = arg.split_once("-W") + .ok_or_else(|| format!("bad week label: {}", arg))?; + let year: i32 = y.parse().map_err(|_| format!("bad week year: {}", arg))?; + let week: u32 = w.parse().map_err(|_| format!("bad week number: {}", arg))?; + let monday = NaiveDate::from_isoywd_opt(year, week, chrono::Weekday::Mon) + .ok_or_else(|| format!("invalid week: {}", arg))?; + let dates = (0..7) + .map(|i| (monday + Duration::days(i)).format("%Y-%m-%d").to_string()) + .collect(); + Ok((arg.to_string(), dates)) + }, date_to_label: |date| week_dates(date).ok().map(|(l, _)| l), }; @@ -60,11 +87,32 @@ const MONTHLY: DigestLevel = DigestLevel { input_title: "Weekly digests", timeout: 600, child_name: Some("weekly"), - label_dates: monthly_label_dates, + label_dates: |arg| { + let (year, month) = if arg.len() <= 7 { + let d = NaiveDate::parse_from_str(&format!("{}-01", arg), "%Y-%m-%d") + .map_err(|e| format!("bad month '{}': {}", arg, e))?; + (d.year(), d.month()) + } else { + let d = NaiveDate::parse_from_str(arg, "%Y-%m-%d") + .map_err(|e| format!("bad date '{}': {}", arg, e))?; + (d.year(), d.month()) + }; + let label = format!("{}-{:02}", year, month); + let mut dates = Vec::new(); + let mut day = 1u32; + while let Some(date) = NaiveDate::from_ymd_opt(year, month, day) { + if date.month() != month { break; } + dates.push(date.format("%Y-%m-%d").to_string()); + day += 1; + } + Ok((label, dates)) + }, date_to_label: |date| NaiveDate::parse_from_str(date, "%Y-%m-%d") .ok().map(|d| format!("{}-{:02}", d.year(), d.month())), }; +const LEVELS: &[&DigestLevel] = &[&DAILY, &WEEKLY, &MONTHLY]; + // --- Input gathering --- /// Load child digest files from the episodic directory. @@ -202,65 +250,8 @@ pub fn generate(store: &mut Store, level_name: &str, arg: &str) -> Result<(), St generate_digest(store, level, &label, &inputs) } -// --- Date helpers --- - -/// Week label and 7 dates (Mon-Sun) for the week containing `date`. -fn week_dates(date: &str) -> Result<(String, Vec), String> { - let nd = NaiveDate::parse_from_str(date, "%Y-%m-%d") - .map_err(|e| format!("bad date '{}': {}", date, e))?; - let iso = nd.iso_week(); - let week_label = format!("{}-W{:02}", iso.year(), iso.week()); - let monday = nd - Duration::days(nd.weekday().num_days_from_monday() as i64); - let dates = (0..7) - .map(|i| (monday + Duration::days(i)).format("%Y-%m-%d").to_string()) - .collect(); - Ok((week_label, dates)) -} - -/// label_dates for weekly: accepts "YYYY-MM-DD" or "YYYY-WNN". -fn weekly_label_dates(arg: &str) -> Result<(String, Vec), String> { - if !arg.contains('W') { - return week_dates(arg); - } - // Parse "YYYY-WNN" - let (y, w) = arg.split_once("-W") - .ok_or_else(|| format!("bad week label: {}", arg))?; - let year: i32 = y.parse().map_err(|_| format!("bad week year: {}", arg))?; - let week: u32 = w.parse().map_err(|_| format!("bad week number: {}", arg))?; - let monday = NaiveDate::from_isoywd_opt(year, week, chrono::Weekday::Mon) - .ok_or_else(|| format!("invalid week: {}", arg))?; - let dates = (0..7) - .map(|i| (monday + Duration::days(i)).format("%Y-%m-%d").to_string()) - .collect(); - Ok((arg.to_string(), dates)) -} - -/// label_dates for monthly: accepts "YYYY-MM" or "YYYY-MM-DD". -fn monthly_label_dates(arg: &str) -> Result<(String, Vec), String> { - let (year, month) = if arg.len() <= 7 { - let d = NaiveDate::parse_from_str(&format!("{}-01", arg), "%Y-%m-%d") - .map_err(|e| format!("bad month '{}': {}", arg, e))?; - (d.year(), d.month()) - } else { - let d = NaiveDate::parse_from_str(arg, "%Y-%m-%d") - .map_err(|e| format!("bad date '{}': {}", arg, e))?; - (d.year(), d.month()) - }; - let label = format!("{}-{:02}", year, month); - let mut dates = Vec::new(); - let mut d = 1u32; - while let Some(date) = NaiveDate::from_ymd_opt(year, month, d) { - if date.month() != month { break; } - dates.push(date.format("%Y-%m-%d").to_string()); - d += 1; - } - Ok((label, dates)) -} - // --- Auto-detect and generate missing digests --- -const LEVELS: &[&DigestLevel] = &[&DAILY, &WEEKLY, &MONTHLY]; - pub fn digest_auto(store: &mut Store) -> Result<(), String> { let today = Local::now().format("%Y-%m-%d").to_string(); let epi = memory_subdir("episodic")?; @@ -308,7 +299,6 @@ pub fn digest_auto(store: &mut Store) -> Result<(), String> { Ok(()) } - // --- Digest link parsing --- // Replaces digest-link-parser.py: parses ## Links sections from digest // files and applies them to the memory graph.