diff options
| -rw-r--r-- | mumctl/src/main.rs | 27 | ||||
| -rw-r--r-- | mumd/src/state.rs | 22 | ||||
| -rw-r--r-- | mumlib/src/config.rs | 40 |
3 files changed, 60 insertions, 29 deletions
diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 0392b2c..6e97296 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -1,7 +1,6 @@ use clap::{App, AppSettings, Arg, Shell, SubCommand}; use colored::Colorize; use ipc_channel::ipc::{self, IpcSender}; -use log::*; use mumlib::command::{Command, CommandResponse}; use mumlib::config; use mumlib::config::ServerConfig; @@ -21,8 +20,10 @@ macro_rules! err_print { fn main() { setup_logger(io::stderr(), true); - let mut config = config::read_default_cfg() - .expect("format error in config file"); + let mut config = config::read_default_cfg(); + if config.is_none() { + println!("{} unable to find config file", "error:".red()); + } let mut app = App::new("mumctl") .setting(AppSettings::ArgRequiredElseHelp) @@ -100,13 +101,21 @@ fn main() { } else if let Some(_) = matches.subcommand_matches("disconnect") { err_print!(send_command(Command::ServerDisconnect)); } else if let Some(matches) = matches.subcommand_matches("config") { - match_server_config(matches, &mut config); + if let Some(config) = &mut config { + match_server_config(matches, config); + } } else if let Some(matches) = matches.subcommand_matches("rename") { - match_server_rename(matches, &mut config); + if let Some(config) = &mut config { + match_server_rename(matches, config); + } } else if let Some(matches) = matches.subcommand_matches("remove") { - match_server_remove(matches, &mut config); + if let Some(config) = &mut config { + match_server_remove(matches, config); + } } else if let Some(matches) = matches.subcommand_matches("add") { - match_server_add(matches, &mut config); + if let Some(config) = &mut config { + match_server_add(matches, config); + } } } else if let Some(matches) = matches.subcommand_matches("channel") { if let Some(_matches) = matches.subcommand_matches("list") { @@ -162,7 +171,9 @@ fn main() { return; }; - config.write_default_cfg(); + if let Some(config) = config { + config.write_default_cfg(); + } } fn match_server_connect(matches : &clap::ArgMatches<>) { diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 08724dd..0dbf9c5 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -22,7 +22,7 @@ pub enum StatePhase { } pub struct State { - config: Config, + config: Option<Config>, server: Option<Server>, audio: Audio, @@ -39,7 +39,7 @@ impl State { ) -> Self { let audio = Audio::new(); let mut state = Self { - config: mumlib::config::read_default_cfg().expect("format error in config file"), + config: mumlib::config::read_default_cfg(), server: None, audio, packet_sender, @@ -208,12 +208,16 @@ impl State { } pub fn reload_config(&mut self) { - self.config = mumlib::config::read_default_cfg() - .expect("format error in config file"); - if let Some(audio_config) = &self.config.audio { - if let Some(input_volume) = audio_config.input_volume { - self.audio.set_input_volume(input_volume); + if let Some(config) = mumlib::config::read_default_cfg() { + self.config = Some(config); + let config = &self.config.as_ref().unwrap(); + if let Some(audio_config) = &config.audio { + if let Some(input_volume) = audio_config.input_volume { + self.audio.set_input_volume(input_volume); + } } + } else { + warn!("config file not found"); } } @@ -224,10 +228,6 @@ impl State { .unwrap(); } - pub fn config(&self) -> &Config { - &self.config - } - pub fn audio(&self) -> &Audio { &self.audio } diff --git a/mumlib/src/config.rs b/mumlib/src/config.rs index 3e55607..aa8a8ed 100644 --- a/mumlib/src/config.rs +++ b/mumlib/src/config.rs @@ -1,3 +1,4 @@ +use log::*; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use std::fs; @@ -17,8 +18,23 @@ pub struct Config { } impl Config { - pub fn write_default_cfg(&self) { - fs::write(get_cfg_path(), toml::to_string(&TOMLConfig::from(self.clone())).unwrap()).unwrap(); + pub fn write_default_cfg(&self) -> Result<(), std::io::Error> { + let path = get_cfg_path(); + let path = std::path::Path::new(&path); + // Possible race here. It's fine since it shows when: + // 1) the file doesn't exist when checked and is then created + // 2) the file exists when checked but is then removed + // If 1) we don't do anything anyway so it's fine, and if 2) we + // immediately re-create the file which, while not perfect, at least + // should work. Unless the file is removed AND the permissions + // change, but then we don't have permissions so we can't + // do anything anyways. + if !path.exists() { + warn!("config file {} does not exist, ignoring", path.display()); + Ok(()) + } else { + fs::write(path, toml::to_string(&TOMLConfig::from(self.clone())).unwrap()) + } } } @@ -67,13 +83,17 @@ impl From<Config> for TOMLConfig { } } -pub fn read_default_cfg() -> Result<Config, toml::de::Error> { - //TODO return None if file doesn't exist (Option::map) - Config::try_from( +pub fn read_default_cfg() -> Option<Config> { + Some(Config::try_from( toml::from_str::<TOMLConfig>( - &fs::read_to_string( - get_cfg_path()) - .expect("config file not found") - .to_string()) - .unwrap()) + &match fs::read_to_string(get_cfg_path()) { + Ok(f) => { + f.to_string() + }, + Err(_) => { + return None + } + } + ).expect("invalid TOML in config file") //TODO + ).expect("invalid config in TOML")) //TODO } |
