diff --git a/src/lib.rs b/src/lib.rs index 86f6f9f..b09ad7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,8 @@ extern crate chrono; +use chrono::Datelike; +use chrono::Local; +use std::collections::HashMap; use std::vec::Vec; #[cfg(test)] @@ -216,3 +219,146 @@ pub fn tokenize(parse_string: &str) -> Vec { let tokenizer = Tokenizer::new(parse_string.to_owned()); tokenizer.collect() } + +fn parse_info(vec: Vec>) -> HashMap { + let mut m = HashMap::new(); + + if vec.len() == 1 { + for (i, val) in vec.get(0).unwrap().into_iter().enumerate() { + m.insert(val.to_lowercase(), i); + } + } else { + for (i, val_vec) in vec.into_iter().enumerate() { + for val in val_vec.into_iter() { + m.insert(val.to_lowercase(), i); + } + } + } + + m +} + +struct ParserInfo { + jump: HashMap, + weekday: HashMap, + months: HashMap, + hms: HashMap, + ampm: HashMap, + utczone: HashMap, + pertain: HashMap, + tzoffset: HashMap, + dayfirst: bool, + yearfirst: bool, + year: u32, + century: u32, +} + + +impl Default for ParserInfo { + fn default() -> Self { + let year = Local::now().year(); + let century = year / 100 * 100; + + ParserInfo { + jump: parse_info(vec![vec![ + " ", ".", ",", ";", "-", "/", "'", + "at", "on", "and", "ad", "m", "t", "of", + "st", "nd", "rd", "th" + ]]), + weekday: parse_info(vec![ + vec!["Mon", "Monday"], + vec!["Tue", "Tues", "Tuesday"], + vec!["Wed", "Wednesday"], + vec!["Thu", "Thurs", "Thursday"], + vec!["Fri", "Friday"], + vec!["Sat", "Saturday"], + vec!["Sun", "Sunday"], + ]), + months: parse_info(vec![ + vec!["Jan", "January"], + vec!["Feb", "February"], + vec!["Mar", "March"], + vec!["Apr", "April"], + vec!["May"], + vec!["Jun", "June"], + vec!["Jul", "July"], + vec!["Aug", "August"], + vec!["Sep", "Sept", "September"], + vec!["Oct", "October"], + vec!["Nov", "November"], + vec!["Dec", "December"], + ]), + hms: parse_info(vec![ + vec!["h", "hour", "hours"], + vec!["m", "minute", "minutes"], + vec!["s", "second", "seconds"], + ]), + ampm: parse_info(vec![ + vec!["am", "a"], + vec!["pm", "p"], + ]), + utczone: parse_info(vec![vec![ + "UTC", "GMT", "Z" + ]]), + pertain: parse_info(vec![vec!["of"]]), + tzoffset: parse_info(vec![vec![]]), + dayfirst: false, + yearfirst: false, + year: year as u32, + century: century as u32, + } + } +} + +impl ParserInfo { + fn get_jump(&self, name: &str) -> bool { + self.jump.contains_key(&name.to_lowercase()) + } + + fn get_weekday(&self, name: &str) -> Option { + self.weekday.get(&name.to_lowercase()).cloned() // TODO: Why do I have to clone a primitive? + } + + fn get_month(&self, name: &str) -> Option { + self.months.get(&name.to_lowercase()).map(|u| u + 1) + } + + fn get_hms(&self, name: &str) -> Option { + self.hms.get(&name.to_lowercase()).cloned() + } + + fn get_ampm(&self, name: &str) -> Option { + self.ampm.get(&name.to_lowercase()).cloned() + } + + fn get_pertain(&self, name: &str) -> bool { + self.pertain.contains_key(&name.to_lowercase()) + } + + fn get_utczone(&self, name: &str) -> bool { + self.utczone.contains_key(&name.to_lowercase()) + } + + fn get_tzoffset(&self, name: &str) -> Option { + if self.utczone.contains_key(&name.to_lowercase()) { + Some(0) + } else { + self.tzoffset.get(&name.to_lowercase()).cloned() + } + } + + fn convertyear(&self, year: u32, century_specified: bool) -> u32 { + let mut year = year; + + if year < 100 && !century_specified { + year += self.century; + if year >= self.year + 50 { + year -= 100; + } else if year < self.year - 50 { + year += 100 + } + } + + year + } +} \ No newline at end of file