move config into its own mod

This commit is contained in:
Fl1tzi 2023-05-22 01:41:53 +02:00
parent df8b668a0a
commit 70ace076f8
3 changed files with 103 additions and 62 deletions

93
src/config.rs Normal file
View file

@ -0,0 +1,93 @@
use crate::Config;
use dirs::config_dir;
use tracing::debug;
use std::{
fmt::{self, Display},
env,
fs,
io::ErrorKind,
path::PathBuf
};
/// The name of the folder which holds the config
pub const CONFIG_FOLDER_NAME: &'static str = "virtual-deck";
#[tracing::instrument]
pub fn load_config() -> Result<Config, ConfigError> {
let config_file: PathBuf = match env::var_os("DACH_DECKER_CONFIG") {
Some(path) => {
debug!("Using env variable: {:?}", path);
PathBuf::from(path)
},
None => {
// try to get the system config dir; env var required if not available
if let Some(mut path) = config_dir() {
path.push(CONFIG_FOLDER_NAME);
path.push("config.toml");
debug!("Using system path: {:?}", path);
path
} else {
return Err(ConfigError::PathNotAvailable())
}
}
};
let path = config_file.display().to_string().clone();
match fs::read_to_string(config_file) {
Ok(content) => toml::from_str(&content).map_err(|e| ConfigError::SyntaxError(e.to_string())),
Err(file_error) => {
if file_error.kind() == ErrorKind::NotFound {
return Err(ConfigError::FilePathDoesNotExist(path))
} else {
return Err(ConfigError::ReadError(file_error.to_string()))
}
}
}
}
#[derive(Debug)]
pub enum ConfigError {
ButtonDoesNotExist(u8),
ModuleDoesNotExist(u8, String),
PathNotAvailable(),
SyntaxError(String),
FilePathDoesNotExist(String),
ReadError(String)
}
impl Display for ConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
ConfigError::ButtonDoesNotExist(index) => {
write!(formatter, "Button {}: does not exist.", index)
}
ConfigError::ModuleDoesNotExist(index, module) => write!(
formatter,
"Button {}: The module \"{}\" does not exist.",
index, module
),
ConfigError::PathNotAvailable() => write!(
formatter,
"Config directory not available. Please use the environment variable \"DACH_DECKER_CONFIG\" to specify the location of the config."
),
ConfigError::SyntaxError(text) => write!(
formatter,
"Syntax error in configuration:\n{}",
text
),
ConfigError::FilePathDoesNotExist(path) => write!(
formatter,
"The configuration file does not exist in {}",
path
),
ConfigError::ReadError(error) => write!(
formatter,
"Could not read the configuration file: {}",
error
)
}
}
}

View file

@ -1,6 +1,7 @@
use crate::{
modules::{retrieve_module_from_name, start_module, HostEvent},
skip_if_none, unwrap_or_error, Button, ConfigError, DeviceConfig,
config::ConfigError,
skip_if_none, unwrap_or_error, Button, DeviceConfig,
};
use deck_driver as streamdeck;
use hidapi::HidApi;

View file

@ -4,27 +4,20 @@ use hidapi::HidApi;
use serde::Deserialize;
use std::{
collections::HashMap,
env,
fmt::{self, Display},
fs,
io::ErrorKind,
path::PathBuf,
process::exit,
sync::Arc,
time::Duration,
time::Duration, process::exit,
};
use tracing::{debug, error, info, warn};
use tracing_subscriber::{
self, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
};
use dirs::config_dir;
use config::load_config;
mod device;
mod modules;
mod config;
/// The name of the folder which holds the config
pub const CONFIG_FOLDER_NAME: &'static str = "virtual-deck";
#[macro_export]
macro_rules! skip_if_none {
@ -67,41 +60,14 @@ fn main() {
.with(fmt_layer)
.init();
// ------ LOAD CONFIG
let config_file: PathBuf = match env::var_os("DACH_DECKER_CONFIG") {
Some(path) => PathBuf::from(path),
None => {
if let Some(mut path) = config_dir() {
path.push(CONFIG_FOLDER_NAME);
path.push("config.toml");
path
} else {
error!("Please use the \"DACH_DECKER_CONFIG\" environment variable to provide a path to your config");
exit(1);
}
let config = match load_config() {
Ok(config) => config,
Err(e) => {
error!("{}", e);
exit(1)
}
};
info!("Loading configuration from \"{}\"", config_file.display());
let config: Config = match fs::read_to_string(config_file) {
Ok(content) => match toml::from_str(&content) {
Ok(c) => c,
Err(e) => {
error!("Error detected in configuration:\n{}", e);
exit(1);
}
},
Err(file_error) => {
if file_error.kind() == ErrorKind::NotFound {
error!("Unable to load configuration because the file does not exist. Please create the configuration file.");
} else {
error!("Cannot open the configuration file: {}", file_error);
}
exit(1);
}
};
debug!("{:#?}", config);
let hid = streamdeck::new_hidapi().expect("Could not create HidApi");
@ -190,25 +156,6 @@ pub async fn start_device(
}
}
pub enum ConfigError {
ButtonDoesNotExist(u8),
ModuleDoesNotExist(u8, String),
}
impl Display for ConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
ConfigError::ButtonDoesNotExist(index) => {
write!(formatter, "Button {}: does not exist.", index)
}
ConfigError::ModuleDoesNotExist(index, module) => write!(
formatter,
"Button {}: The module \"{}\" does not exist.",
index, module
),
}
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct DeviceConfig {