use anyhow::Result; use chrono::{Local, NaiveDate, NaiveDateTime, TimeZone}; use rusqlite::Connection; use crate::model::event::Event; use crate::{db, model::event}; pub fn today(conn: &Connection) -> Result { let today = Local::now().date_naive(); let events = between_inclusive(conn, today, today)?; Ok(format_events(events)) } pub fn parse_timestamp_range(s: String) -> Option<(NaiveDateTime, NaiveDateTime)> { match s.split("..").collect::>()[..] { [from, to] => { let from = from.parse().ok()?; let to = to.parse().ok()?; let from = Local.timestamp_opt(from, 0).single()?; let to = Local.timestamp_opt(to, 0).single()?; Some((from.naive_local(), to.naive_local())) } _ => None, } } pub fn start_between(conn: &Connection, from: NaiveDateTime, to: NaiveDateTime) -> Result { let from_date = from.date(); let to_date = to.date(); let events = between_inclusive(conn, from_date, to_date)?; let events: Vec = events .iter() .filter(|e| match e.start { None => false, Some(t) => { let dt = NaiveDateTime::new(e.date, t); dt >= from && dt < to } }) .cloned() .collect::>(); Ok(format_events(events)) } fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Result> { let mut events = db::events::list_non_recurring_between(conn, from, to)?; let recurring_events = db::events::list_recurring(conn)?; let repetitions = event::repetitions_between(&recurring_events, from, to); for (date, original_events) in repetitions.iter() { for original_event in original_events { let event = Event { date: *date, ..original_event.clone() }; events.push(event); } } Ok(events) } fn format_events(events: Vec) -> String { let mut events = events; events.sort_by_key(|e| e.local_timestamp()); events .iter() .map(|e| format!("{}\n", e.pprint())) .collect::>() .join("") }