diff --git a/src/config.rs b/src/config.rs index 318ea4e..187fb9f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,7 +20,35 @@ use std::{ io::Read, fs::read_dir, }; -use toml::value::Value; +use toml::{ + value::Value, + map::Map, +}; + +fn parse_toml_to_table(path: PathBuf) + -> Result, Box> { + // I once read that this multiple let style + // is the "rusty" way to do things. + // Personally, I find this specific instance to be somewhat sketchy. + let mut config = String::new(); + std::fs::File::open(path)? + .read_to_string(&mut config)?; + let mut config = config.parse::()?; + // The important thing here is that config is a mut Table in the end. + Ok(config.as_table_mut().unwrap().clone()) +} + +fn merge_config_maps(mut receiver: Map, donor: Map) + -> Result, Box> { + for key in donor.keys() { + if receiver.contains_key(&key.clone()) { + receiver[&key.clone()] = donor[key].clone(); + } else { + receiver.insert(key.clone(), donor[key].clone()); + } + } + Ok(receiver) +} fn parse_server_dir(mut config: Value, server_config_path: PathBuf) -> Result> { @@ -29,9 +57,22 @@ fn parse_server_dir(mut config: Value, server_config_path: PathBuf) for entry in read_dir(server_config_path)? { let entry = entry?; match entry.file_name().to_str().ok_or("Could not read file name")? { - "config.toml" => (), - "clients.toml" => (), - "channels.toml" => (), + "config.toml" => { + let server_config = parse_toml_to_table(entry.path())?; + config = merge_config_maps(config, server_config)?; + }, + "clients.toml" => { + let client_config = parse_toml_to_table(entry.path())?; + config = merge_config_maps(config, client_config)?; + }, + "channels.toml" => { + let channels = Value::from(parse_toml_to_table(entry.path())?); + if config.contains_key(&"channels".to_owned()) { + config[&"channels".to_owned()] = channels; + } else { + config.insert("channels".to_owned(), channels); + } + }, _ => (), } } @@ -45,17 +86,8 @@ fn parse_server_dir(mut config: Value, server_config_path: PathBuf) // TODO: Document config file options once they are stable. pub fn get_main_config(config_path: PathBuf) -> Result> { + let mut config = parse_toml_to_table(config_path)?; - // I once read that this multiple let style - // is the "rusty" way to do things. - // Personally, I find this specific instance to be somewhat sketchy. - let mut config = String::new(); - std::fs::File::open(config_path)? - .read_to_string(&mut config)?; - let mut config = config.parse::()?; - // The important thing here is that config is a mut Table in the end. - let mut config = config.as_table_mut().unwrap().clone(); - if config.get("port") == None { config.insert(String::from("port"), Value::from("6697")); } @@ -73,16 +105,17 @@ pub fn get_main_config(config_path: PathBuf) Ok(Value::from(config)) } -pub fn get_server_config(mut config: Value, config_path: PathBuf) - -> Result> { +pub fn get_server_configs(config: Value, config_path: PathBuf) + -> Result, Box> { + let mut config_vec = vec![]; if config_path.is_dir() { for entry in read_dir(config_path)? { let entry = entry?; let server_path = entry.path(); if server_path.is_dir(){ - config = parse_server_dir(config, server_path)?; + config_vec.push(parse_server_dir(config.clone(), server_path)?); } } } - Ok(config) + Ok(config_vec) } diff --git a/src/main.rs b/src/main.rs index 3d7f23b..d1c86b8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -152,7 +152,7 @@ fn main() { } } - let mut config; + let config; match config_path { Some(p) => config = config::get_main_config(PathBuf::from(p)) @@ -161,8 +161,10 @@ fn main() { .expect("Could not get default config in /etc/Mention2Mail/default.toml"), } + let mut server_configs; + match server_conf_path { - Some(p) => config = config::get_server_config(config, PathBuf::from(p)) + Some(p) => server_configs = config::get_server_configs(config, PathBuf::from(p)) .expect("Could not get server config."), None => (), }