aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mumctl/src/main.rs27
-rw-r--r--mumd/src/state.rs22
-rw-r--r--mumlib/src/config.rs40
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
}