use std::collections::HashMap; use chrono::{NaiveDate, NaiveDateTime}; mod tokenizer; mod parser; pub use parser::Parser; pub trait GetValue<'a, R: 'a> { fn get(&'a self, key: &'_ str) -> Option; } pub type Props = Vec<(String, String)>; #[derive(Debug, PartialEq)] pub struct Object { pub name: String, pub content: HashMap, pub children: Vec>, } impl<'a> GetValue<'a, &'a str> for Object { fn get(&'a self, key: &'_ str) -> Option<&'a str> { self.content.get(key) .map(|(_props, value)| value.as_ref()) } } impl<'a> GetValue<'a, String> for Object { fn get(&self, key: &'_ str) -> Option { self.content.get(key) .map(|(_props, value)| value.clone()) } } // TODO: TZID, offset // TODO: enum for all day events? impl<'a> GetValue<'a, NaiveDateTime> for Object { fn get(&self, key: &'_ str) -> Option { let s = self.get(key)?; NaiveDateTime::parse_from_str(s, "%Y%m%dT%H%M%SZ") .or_else(|_| NaiveDateTime::parse_from_str(s, "%Y%m%dT%H%M%S")) .or_else(|_| NaiveDate::parse_from_str(s, "%Y%m%d") .map(|date| date.and_hms(0, 0, 0)) ) .map_err(|e| println!("Cannot parse date: {:?}", e)) .ok() } }