You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
4.8 KiB
Rust

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<usize, String>,
sections: HashMap<String, Section>,
}
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<String, Entry>,
}
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<bool> {
self.entries.get(name).and_then(|x| x.get_boolean())
}
fn get_list(&self, name: &str) -> Option<Vec<&str>> {
self.entries.get(name).map(|x| x.get_list())
}
fn get_time_span(&self, name: &str) -> Option<TimeSpan> {
self.entries.get(name).and_then(|x| x.get_time_span())
}
}
#[derive(Clone, Debug, Default)]
struct Entry {
name: String,
values: Vec<EntryValue>,
}
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<bool> {
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<TimeSpan> {
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,
}