use std::collections::HashMap; use crate::config::parser::parse_time_span; pub mod parser; #[derive(Clone, Debug, Default)] struct Config { name: String, file_pointer: usize, files: HashMap, sections: HashMap, } impl Config { pub(crate) fn add_file(&mut self, file_name: String) -> usize { let id = self.file_pointer; self.file_pointer += 1; self.files.insert(id, file_name); id } } #[derive(Clone, Debug, Default)] struct Section { name: String, entries: HashMap, } impl Section { pub fn new(name: String) -> Section { Section { name, entries: HashMap::new(), } } pub fn entry(&self, name: &str) -> Option<&Entry> { self.entries.get(name) } fn get_string(&self, name: &str) -> Option<&str> { self.entries.get(name).map(|x| x.get_string()) } fn get_boolean(&self, name: &str) -> Option { self.entries.get(name).and_then(|x| x.get_boolean()) } fn get_list(&self, name: &str) -> Option> { self.entries.get(name).map(|x| x.get_list()) } fn get_time_span(&self, name: &str) -> Option { self.entries.get(name).and_then(|x| x.get_time_span()) } } #[derive(Clone, Debug, Default)] struct Entry { name: String, values: Vec, } impl Entry { pub fn new(name: String) -> Entry { Entry { name, values: Vec::new(), } } pub fn add(&mut self, value: &str, file_id: usize) { self.values.push(EntryValue { value: value.to_string(), file_id }) } pub fn get_string(&self) -> &str { self.last_value().unwrap_or("") } pub fn get_list(&self) -> Vec<&str> { self.values.iter() .map(|x| x.value.as_str()) .fold(Vec::new(), |mut acc, val| { if val == "" { acc.clear() } else { acc.push(val) } acc }) } fn last_value(&self) -> Option<&str> { self.values.last().map(|x| x.value.as_str()) } pub fn get_boolean(&self) -> Option { self.last_value().and_then(|value| { match value { "yes" | "true" | "1" | "on" => { Some(true) } "no" | "false" | "0" | "off" => { Some(false) } _ => None } }) } pub fn get_time_span(&self) -> Option { self.last_value().and_then(parse_time_span) } } #[derive(Default, Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)] pub struct TimeSpan { pub years: usize, pub months: usize, pub weeks: usize, pub days: usize, pub hours: usize, pub minutes: usize, pub seconds: usize, pub milliseconds: usize, pub microseconds: usize, pub nanoseconds: usize, } impl TimeSpan { pub fn with_years(&self, years: usize) -> TimeSpan { let mut new = self.clone(); new.years = years; new } pub fn with_months(&self, months: usize) -> TimeSpan { let mut new = self.clone(); new.months = months; new } pub fn with_weeks(&self, weeks: usize) -> TimeSpan { let mut new = self.clone(); new.weeks = weeks; new } pub fn with_days(&self, days: usize) -> TimeSpan { let mut new = self.clone(); new.days = days; new } pub fn with_hours(&self, hours: usize) -> TimeSpan { let mut new = self.clone(); new.hours = hours; new } pub fn with_minutes(&self, minutes: usize) -> TimeSpan { let mut new = self.clone(); new.minutes = minutes; new } pub fn with_seconds(&self, seconds: usize) -> TimeSpan { let mut new = self.clone(); new.seconds = seconds; new } pub fn with_milliseconds(&self, milliseconds: usize) -> TimeSpan { let mut new = self.clone(); new.milliseconds = milliseconds; new } pub fn with_microseconds(&self, microseconds: usize) -> TimeSpan { let mut new = self.clone(); new.microseconds = microseconds; new } pub fn with_nanoseconds(&self, nanoseconds: usize) -> TimeSpan { let mut new = self.clone(); new.nanoseconds = nanoseconds; new } pub fn new() -> TimeSpan { TimeSpan { years: 0, months: 0, weeks: 0, days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0, microseconds: 0, nanoseconds: 0, } } } #[derive(Clone, Debug, Default)] struct EntryValue { value: String, file_id: usize, }