use glob::Pattern;
use logging::*;
use std::collections::HashMap;
use std::f64::INFINITY;
use std::str::FromStr;
pub struct Config
{
pub home_path: String,
pub address: String,
pub time_units: f64,
pub max_secs: f64,
pub num_init_stages: i32,
pub seed: usize,
pub log_level: LogLevel,
pub log_levels: HashMap<Pattern, LogLevel>,
pub max_log_path: usize,
pub colorize: bool,
pub error_escape_code: String,
pub warning_escape_code: String,
pub info_escape_code: String,
pub debug_escape_code: String,
pub excessive_escape_code: String,
}
impl Config
{
pub fn new() -> Config
{
Config {
home_path: "".to_string(),
address: "127.0.0.1:9000".to_string(),
time_units: 1_000_000.0,
max_secs: INFINITY,
num_init_stages: 1,
seed: 0,
log_level: LogLevel::Info,
log_levels: HashMap::new(),
max_log_path: 20,
colorize: true,
error_escape_code: "\x1b[31;1m".to_string(),
warning_escape_code: "\x1b[31m".to_string(),
info_escape_code: "\x1b[30;1m".to_string(),
debug_escape_code: "".to_string(),
excessive_escape_code: "\x1b[1;38;5;244m".to_string(),
}
}
pub fn parse_max_secs(&mut self, text: &str) -> Option<&'static str>
{
let mut text = text.to_string();
let units = text.pop().unwrap();
if let Ok(base) = f64::from_str(&text) {
match units { 's' => {self.max_secs = base; None},
'm' => {self.max_secs = 60.0*base; None},
'h' => {self.max_secs = 60.0*60.0*base; None},
'd' => {self.max_secs = 24.0*60.0*60.0*base; None},
'w' => {self.max_secs = 7.0*24.0*60.0*60.0*base; None},
_ => Some("--max-secs should have an s, m, h, d, or w suffix")
}
} else {
Some("--max-secs should have an f64 value followed by a suffix")
}
}
pub fn parse_log_level(&mut self, level: &str) -> Option<&'static str>
{
match do_parse_log_level(level) {
Ok(value) => {
self.log_level = value;
None
},
Err(message) => Some(message)
}
}
pub fn parse_log_levels(&mut self, values: Vec<&str>) -> Option<String>
{
for entry in values {
let parts: Vec<&str> = entry.splitn(2, ':').collect();
if parts.len() == 2 {
match do_parse_log_level(parts[0]) {
Ok(level) => {
if let Ok(pattern) = Pattern::new(parts[1]) {
self.log_levels.insert(pattern, level); } else {
return Some(format!("--log={} has a malformed glob", entry));
}
},
Err(message) => {return Some(message.to_string());}
}
} else {
return Some(format!("--log={} should be formatted as LEVEL:GLOB", entry));
}
}
None
}
}
pub fn time_suffixes() -> &'static str
{
"s, m, h, d, or w"
}
fn do_parse_log_level(level: &str) -> Result<LogLevel, &'static str>
{
match level {
"error" => Ok(LogLevel::Error),
"warning" => Ok(LogLevel::Warning),
"info" => Ok(LogLevel::Info),
"debug" => Ok(LogLevel::Debug),
"excessive" => Ok(LogLevel::Excessive),
_ => Err("--log-level should be error, warning, info, debug, or excessive"),
}
}