Add ParserInfo struct

pull/1/head
Bradlee Speice 2018-05-17 22:56:46 -04:00
parent 58e3b05b45
commit 5beff61366
1 changed files with 146 additions and 0 deletions

View File

@ -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<Token> {
let tokenizer = Tokenizer::new(parse_string.to_owned());
tokenizer.collect()
}
fn parse_info(vec: Vec<Vec<&str>>) -> HashMap<String, usize> {
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<String, usize>,
weekday: HashMap<String, usize>,
months: HashMap<String, usize>,
hms: HashMap<String, usize>,
ampm: HashMap<String, usize>,
utczone: HashMap<String, usize>,
pertain: HashMap<String, usize>,
tzoffset: HashMap<String, usize>,
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<usize> {
self.weekday.get(&name.to_lowercase()).cloned() // TODO: Why do I have to clone a primitive?
}
fn get_month(&self, name: &str) -> Option<usize> {
self.months.get(&name.to_lowercase()).map(|u| u + 1)
}
fn get_hms(&self, name: &str) -> Option<usize> {
self.hms.get(&name.to_lowercase()).cloned()
}
fn get_ampm(&self, name: &str) -> Option<usize> {
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<usize> {
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
}
}