aboutsummaryrefslogtreecommitdiff
path: root/src/cli/mod.rs
blob: 3674a080e9da5122ec279c79e76b9c7b683008c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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<String> {
    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::<Vec<&str>>()[..] {
        [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<String> {
    let from_date = from.date();
    let to_date = to.date();
    let events = between_inclusive(conn, from_date, to_date)?;
    let events: Vec<Event> = events
        .iter()
        .filter(|e| match e.start {
            None => false,
            Some(t) => {
                let dt = NaiveDateTime::new(e.date, t);
                dt >= from && dt < to
            }
        })
        .cloned()
        .collect::<Vec<Event>>();
    Ok(format_events(events))
}

fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Result<Vec<Event>> {
    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<Event>) -> String {
    let mut events = events;
    events.sort_by_key(|e| e.local_timestamp());
    events
        .iter()
        .map(|e| format!("{}\n", e.pprint()))
        .collect::<Vec<String>>()
        .join("")
}