mirror of
https://codeberg.org/Fl1tzi/microdeck.git
synced 2024-05-19 19:20:20 +00:00
move config into its own mod
This commit is contained in:
parent
df8b668a0a
commit
70ace076f8
93
src/config.rs
Normal file
93
src/config.rs
Normal 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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
modules::{retrieve_module_from_name, start_module, HostEvent},
|
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 deck_driver as streamdeck;
|
||||||
use hidapi::HidApi;
|
use hidapi::HidApi;
|
||||||
|
|
69
src/main.rs
69
src/main.rs
|
@ -4,27 +4,20 @@ use hidapi::HidApi;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
env,
|
|
||||||
fmt::{self, Display},
|
|
||||||
fs,
|
|
||||||
io::ErrorKind,
|
|
||||||
path::PathBuf,
|
|
||||||
process::exit,
|
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration, process::exit,
|
||||||
};
|
};
|
||||||
use tracing::{debug, error, info, warn};
|
use tracing::{debug, error, info, warn};
|
||||||
use tracing_subscriber::{
|
use tracing_subscriber::{
|
||||||
self, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
|
self, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
use dirs::config_dir;
|
use config::load_config;
|
||||||
|
|
||||||
mod device;
|
mod device;
|
||||||
mod modules;
|
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_export]
|
||||||
macro_rules! skip_if_none {
|
macro_rules! skip_if_none {
|
||||||
|
@ -67,41 +60,14 @@ fn main() {
|
||||||
.with(fmt_layer)
|
.with(fmt_layer)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
// ------ LOAD CONFIG
|
let config = match load_config() {
|
||||||
|
Ok(config) => config,
|
||||||
let config_file: PathBuf = match env::var_os("DACH_DECKER_CONFIG") {
|
Err(e) => {
|
||||||
Some(path) => PathBuf::from(path),
|
error!("{}", e);
|
||||||
None => {
|
exit(1)
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
debug!("{:#?}", config);
|
||||||
|
|
||||||
let hid = streamdeck::new_hidapi().expect("Could not create HidApi");
|
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)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct DeviceConfig {
|
pub struct DeviceConfig {
|
||||||
|
|
Loading…
Reference in a new issue