From 950158eaadd8db9ef0eb48187e825524499422d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustav=20S=C3=B6rn=C3=A4s?= Date: Tue, 30 Mar 2021 12:36:53 +0200 Subject: config error --- mumctl/src/main.rs | 8 +++++++- mumd/src/error.rs | 9 +++++++++ mumd/src/state.rs | 9 +++++++-- mumlib/src/config.rs | 23 +++++++++++++---------- mumlib/src/error.rs | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 13 deletions(-) diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs index 2d9cd18..a187a3a 100644 --- a/mumctl/src/main.rs +++ b/mumctl/src/main.rs @@ -44,7 +44,13 @@ static LOGGER: SimpleLogger = SimpleLogger; fn main() { log::set_logger(&LOGGER) .map(|()| log::set_max_level(LevelFilter::Info)).unwrap(); - let mut config = config::read_default_cfg(); + let mut config = match config::read_default_cfg() { + Ok(c) => c, + Err(e) => { + error!("Couldn't read config: {}", e); + return; + } + }; let mut app = App::new("mumctl") .setting(AppSettings::ArgRequiredElseHelp) diff --git a/mumd/src/error.rs b/mumd/src/error.rs index a171f1f..84c1958 100644 --- a/mumd/src/error.rs +++ b/mumd/src/error.rs @@ -1,3 +1,4 @@ +use mumlib::error::ConfigError; use std::fmt; pub enum AudioStream { @@ -36,6 +37,7 @@ impl fmt::Display for AudioError { pub enum StateError { AudioError(AudioError), + ConfigError(ConfigError), } impl From for StateError { @@ -44,10 +46,17 @@ impl From for StateError { } } +impl From for StateError { + fn from(e: ConfigError) -> Self { + StateError::ConfigError(e) + } +} + impl fmt::Display for StateError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { StateError::AudioError(e) => write!(f, "Audio error: {}", e), + StateError::ConfigError(e) => write!(f, "Config error: {}", e), } } } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 9202e9f..b52b330 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -64,7 +64,7 @@ pub struct State { impl State { pub fn new() -> Result { - let config = mumlib::config::read_default_cfg(); + let config = mumlib::config::read_default_cfg()?; let phase_watcher = watch::channel(StatePhase::Disconnected); let audio = Audio::new( config.audio.input_volume.unwrap_or(1.0), @@ -574,7 +574,12 @@ impl State { } pub fn reload_config(&mut self) { - self.config = mumlib::config::read_default_cfg(); + match mumlib::config::read_default_cfg() { + Ok(config) => { + self.config = config; + } + Err(e) => error!("Couldn't read config: {}", e), + } if let Some(input_volume) = self.config.audio.input_volume { self.audio.set_input_volume(input_volume); } diff --git a/mumlib/src/config.rs b/mumlib/src/config.rs index 74b4b9c..9394b85 100644 --- a/mumlib/src/config.rs +++ b/mumlib/src/config.rs @@ -1,4 +1,6 @@ +use crate::error::ConfigError; use crate::DEFAULT_PORT; + use log::*; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; @@ -21,7 +23,7 @@ pub struct Config { } impl Config { - pub fn write_default_cfg(&self, create: bool) -> Result<(), std::io::Error> { + pub fn write_default_cfg(&self, create: bool) -> Result<(), ConfigError> { let path = default_cfg_path(); // Possible race here. It's fine since it shows when: @@ -34,13 +36,13 @@ impl Config { // do anything anyways. if !create && !path.exists() { - return Ok(()); + return Err(ConfigError::WontCreateFile); } - fs::write( + Ok(fs::write( &path, - toml::to_string(&TOMLConfig::from(self.clone())).unwrap(), //TODO handle panic - ) + toml::to_string(&TOMLConfig::from(self.clone()))?, + )?) } } @@ -139,19 +141,20 @@ impl From for TOMLConfig { config .servers .into_iter() - .map(|s| Value::try_from::(s).unwrap()) //TODO handle panic + // Safe since all ServerConfigs are valid TOML + .map(|s| Value::try_from::(s).unwrap()) .collect(), ), } } } -pub fn read_default_cfg() -> Config { +pub fn read_default_cfg() -> Result { let path = default_cfg_path(); match fs::read_to_string(&path) { Ok(s) => { - let toml_config: TOMLConfig = toml::from_str(&s).expect("Invalid TOML in config file"); //TODO handle panic - return Config::try_from(toml_config).expect("Invalid config in TOML"); //TODO handle panic + let toml_config: TOMLConfig = toml::from_str(&s)?; + Ok(Config::try_from(toml_config)?) }, Err(e) => { if matches!(e.kind(), std::io::ErrorKind::NotFound) && !path.exists() { @@ -159,7 +162,7 @@ pub fn read_default_cfg() -> Config { } else { error!("Error reading config file: {}", e); } - return Config::default(); + return Ok(Config::default()); } } } diff --git a/mumlib/src/error.rs b/mumlib/src/error.rs index f6a02a7..6b7dccd 100644 --- a/mumlib/src/error.rs +++ b/mumlib/src/error.rs @@ -42,3 +42,42 @@ impl fmt::Display for ChannelIdentifierError { } } } + +pub enum ConfigError { + InvalidConfig, + TOMLErrorSer(toml::ser::Error), + TOMLErrorDe(toml::de::Error), + + WontCreateFile, + IOError(std::io::Error), +} + +impl fmt::Display for ConfigError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ConfigError::InvalidConfig => write!(f, "Invalid configuration"), + ConfigError::TOMLErrorSer(e) => write!(f, "Invalid TOML when serializing: {}", e), + ConfigError::TOMLErrorDe(e) => write!(f, "Invalid TOML when deserializing: {}", e), + ConfigError::WontCreateFile => write!(f, "File does not exist but caller didn't allow creation"), + ConfigError::IOError(e) => write!(f, "IO error: {}", e), + } + } +} + +impl From for ConfigError { + fn from(e: std::io::Error) -> Self { + ConfigError::IOError(e) + } +} + +impl From for ConfigError { + fn from(e: toml::ser::Error) -> Self { + ConfigError::TOMLErrorSer(e) + } +} + +impl From for ConfigError { + fn from(e: toml::de::Error) -> Self { + ConfigError::TOMLErrorDe(e) + } +} -- cgit v1.2.1