use serde_json::Value; use crate::{ BucketKind, LoadedEntry, Result, UsageSummary, cli::{AgentReportKind, WeekDay}, summarize_by_key, summarize_summaries_by_bucket, totals_json, }; pub fn report_from_rows(rows: &[UsageSummary], kind: AgentReportKind) -> Value { let rows_json = rows .iter() .map(|row| ccusage_core::agent_summary_json(row, kind, false)) .collect::>(); serde_json::json!({ rows_key(kind): rows_json, "totals": totals_json(rows), }) } pub(super) fn summary_period(row: &UsageSummary) -> &str { row.date .as_deref() .or(row.week.as_deref()) .or(row.month.as_deref()) .or(row.session_id.as_deref()) .unwrap_or("") } pub fn summarize_entries( entries: &[LoadedEntry], kind: AgentReportKind, ) -> Result> { match kind { AgentReportKind::Daily => summarize_by_key( entries, |entry| entry.date.clone(), |date| (date.to_string(), None), ), AgentReportKind::Monthly => { let daily = summarize_entries(entries, AgentReportKind::Daily)?; Ok(summarize_summaries_by_bucket( &daily, BucketKind::Monthly, WeekDay::Sunday, )) } AgentReportKind::Session => summarize_by_key( entries, |entry| entry.session_id.to_string(), |session_id| (session_id.to_string(), None), ) .map(|mut rows| { for row in &mut rows { row.session_id = row.date.take(); } rows }), AgentReportKind::Weekly => { let daily = summarize_entries(entries, AgentReportKind::Daily)?; Ok(summarize_summaries_by_bucket( &daily, BucketKind::Weekly, WeekDay::Sunday, )) } } } fn rows_key(kind: AgentReportKind) -> &'static str { match kind { AgentReportKind::Daily => "daily", AgentReportKind::Weekly => "weekly", AgentReportKind::Monthly => "monthly", AgentReportKind::Session => "sessions", } }