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
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,
|
|
} |