caltemps 0.2.1

A tool to query and report on your iCalendar data from vDirs.
Documentation
use chrono::{DateTime, Datelike, Local, TimeZone};
use icalendar::{Component, DatePerhapsTime};

use super::date_range::CalTempsDateRange;

#[derive(Debug)]
pub struct CalTempsEntry {
    pub is_event: bool,
    pub summary: String,
    pub description: String,
    pub start: Option<DateTime<Local>>,
    pub end: Option<DateTime<Local>>,
}

fn dpt_to_dt(dpt: Option<DatePerhapsTime>) -> Option<DateTime<Local>> {
    match dpt {
        Some(icalendar::DatePerhapsTime::DateTime(cdt)) => cdt.try_into_utc().map(|d| d.into()),
        Some(icalendar::DatePerhapsTime::Date(nd)) => Some(
            Local
                .with_ymd_and_hms(nd.year(), nd.month(), nd.day(), 0, 0, 0)
                .unwrap(),
        ),
        _ => None,
    }
}

fn get_matching_entry_basic(
    active_filter: String,
    date_range: &CalTempsDateRange,
    summary: Option<&str>,
    description: Option<&str>,
    start: Option<DateTime<Local>>,
    end: Option<DateTime<Local>>,
) -> Option<CalTempsEntry> {
    if let Some(summary_str) = summary {
        if summary_str.contains(&active_filter) {
            return match start {
                Some(dts) => {
                    if date_range.start.unwrap_or(dts) <= dts {
                        match end {
                            Some(dte) => {
                                if dte <= date_range.end.unwrap_or(dte) {
                                    Some(CalTempsEntry {
                                        summary: summary_str.into(),
                                        description: description.unwrap_or_default().into(),
                                        start,
                                        end,
                                        is_event: true,
                                    })
                                } else {
                                    // Ignore those not matching end
                                    None
                                }
                            }
                            // Ignore those without end data(!)
                            _ => None,
                        }
                    } else {
                        // Ignore not matching start data
                        None
                    }
                }
                // Ignoring those without start data
                _ => None,
            };
        }
    }
    // Ignoring invalid or non-matching summaries
    None
}

pub fn get_matching_entry(
    component: icalendar::CalendarComponent,
    active_filter: String,
    date_range: &CalTempsDateRange,
) -> Option<CalTempsEntry> {
    match component {
        icalendar::CalendarComponent::Event(item) => get_matching_entry_basic(
            active_filter,
            date_range,
            item.get_summary(),
            item.get_description(),
            dpt_to_dt(item.get_start()),
            dpt_to_dt(item.get_end()),
        ),
        // TODO: we may want to implement support for other components
        _ => None,
    }
}