digest: remove dead iso_week_info, use chrono directly everywhere

Deleted iso_week_info() — dead code after week_dates() was rewritten.
Replaced remaining epoch_to_local/today/now_epoch calls with chrono
Local::now() and NaiveDate parsing. Month arg parsing now uses
NaiveDate instead of manual string splitting. Phase 3 month
comparison simplified to a single tuple comparison.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2026-03-03 17:26:01 -05:00
parent f4364e299c
commit f415a0244f
2 changed files with 111 additions and 33 deletions

View file

@ -143,16 +143,6 @@ fn week_dates(date: &str) -> Result<(String, Vec<String>), String> {
Ok((week_label, dates))
}
/// Returns (weekday 0=Sun, iso_year, iso_week) for a given date.
fn iso_week_info(y: i32, m: u32, d: u32) -> Result<(u32, i32, u32), String> {
use chrono::{Datelike, NaiveDate};
let date = NaiveDate::from_ymd_opt(y, m, d)
.ok_or_else(|| format!("invalid date: {}-{}-{}", y, m, d))?;
let wday = date.weekday().num_days_from_sunday();
let iso = date.iso_week();
Ok((wday, iso.year(), iso.week()))
}
fn load_digest_files(prefix: &str, labels: &[String]) -> Result<Vec<(String, String)>, String> {
let dir = memory_subdir("episodic")?;
let mut digests = Vec::new();
@ -273,18 +263,14 @@ fn build_monthly_prompt(month_label: &str, digests: &[(String, String)], keys: &
}
pub fn generate_monthly(store: &mut Store, month_arg: &str) -> Result<(), String> {
use chrono::{Datelike, Local, NaiveDate};
let (year, month) = if month_arg.is_empty() {
let now = store::now_epoch();
let (y, m, _, _, _, _) = store::epoch_to_local(now);
(y, m)
let now = Local::now();
(now.year(), now.month())
} else {
let parts: Vec<&str> = month_arg.split('-').collect();
if parts.len() != 2 {
return Err(format!("bad month format: {} (expected YYYY-MM)", month_arg));
}
let y: i32 = parts[0].parse().map_err(|_| "bad year")?;
let m: u32 = parts[1].parse().map_err(|_| "bad month")?;
(y, m)
let d = NaiveDate::parse_from_str(&format!("{}-01", month_arg), "%Y-%m-%d")
.map_err(|e| format!("bad month '{}': {} (expected YYYY-MM)", month_arg, e))?;
(d.year(), d.month())
};
let month_label = format!("{}-{:02}", year, month);
@ -340,7 +326,9 @@ pub fn generate_monthly(store: &mut Store, month_arg: &str) -> Result<(), String
/// (needs weeklies). Skips today (incomplete day). Skips already-existing
/// digests.
pub fn digest_auto(store: &mut Store) -> Result<(), String> {
let today = store::today();
use chrono::{Datelike, Local};
let now = Local::now();
let today = now.format("%Y-%m-%d").to_string();
let epi = memory_subdir("episodic")?;
// --- Phase 1: find dates with journal entries but no daily digest ---
@ -430,15 +418,12 @@ pub fn digest_auto(store: &mut Store) -> Result<(), String> {
// A month is "ready" if the month is before the current month and at
// least one weekly digest exists for it.
let (cur_y, cur_m, _, _, _, _) = store::epoch_to_local(store::now_epoch());
let cur_month = (now.year(), now.month());
let mut months_seen: std::collections::BTreeSet<(i32, u32)> = std::collections::BTreeSet::new();
for date in &daily_dates_done {
let parts: Vec<&str> = date.split('-').collect();
if parts.len() >= 2 {
if let (Ok(y), Ok(m)) = (parts[0].parse::<i32>(), parts[1].parse::<u32>()) {
months_seen.insert((y, m));
}
if let Ok(nd) = chrono::NaiveDate::parse_from_str(date, "%Y-%m-%d") {
months_seen.insert((nd.year(), nd.month()));
}
}
@ -446,12 +431,8 @@ pub fn digest_auto(store: &mut Store) -> Result<(), String> {
let mut monthly_skipped = 0u32;
for (y, m) in &months_seen {
// Skip current month (still in progress)
if *y == cur_y && *m == cur_m {
continue;
}
// Skip future months
if *y > cur_y || (*y == cur_y && *m > cur_m) {
// Skip current or future months
if (*y, *m) >= cur_month {
continue;
}