iowo/crates/app/src/config.rs

99 lines
2.9 KiB
Rust
Raw Permalink Normal View History

use std::path::PathBuf;
2024-01-15 08:03:55 +00:00
use clap::Parser;
2024-01-12 08:36:30 +00:00
use self::{
cli::Args,
config_file::{find_config_file, Configs},
};
2024-01-12 08:36:30 +00:00
2024-01-15 08:03:55 +00:00
mod cli;
mod config_file;
2024-01-12 08:36:30 +00:00
2024-01-15 08:03:55 +00:00
/// this struct may hold all configuration
pub struct Config {
pub source: PathBuf,
pub evaluator: eval::Available,
2024-01-15 08:03:55 +00:00
pub startup_msg: bool,
2024-01-12 08:36:30 +00:00
}
2024-01-15 08:03:55 +00:00
impl Config {
2024-01-19 08:51:48 +00:00
/// Get the configs from all possible places (args, file, env...)
2024-01-19 07:54:36 +00:00
pub fn read() -> Self {
2024-01-15 08:03:55 +00:00
let args = Args::parse();
let config = if let Some(config) = args.config_path {
Ok(config)
} else {
2024-01-19 07:54:36 +00:00
find_config_file()
};
2024-01-12 08:36:30 +00:00
2024-01-19 08:51:48 +00:00
// try to read a maybe existing config file
let config = config.ok().and_then(|path| {
Configs::read(path).map_or_else(
|e| {
2024-01-19 07:54:36 +00:00
eprintln!("Config error: {e:?}");
eprintln!("Proceeding with defaults or cli args...");
None
},
Some,
)
});
2024-01-19 07:54:36 +00:00
if let Some(file) = config {
2024-01-19 07:54:36 +00:00
Self {
source: args.source,
evaluator: args.evaluator.and(file.evaluator).unwrap_or_default(),
2024-01-19 07:54:36 +00:00
// this is negated because to an outward api, the negative is more intuitive,
// while in the source the other way around is more intuitive
startup_msg: !(args.no_startup_message || file.no_startup_message),
2024-01-19 07:54:36 +00:00
}
} else {
Self {
source: args.source,
2024-01-19 07:54:36 +00:00
startup_msg: !args.no_startup_message,
evaluator: args.evaluator.unwrap_or_default(),
2024-01-19 07:54:36 +00:00
}
}
}
}
pub mod error {
2024-01-19 08:51:48 +00:00
/// Errors that can occur when reading configs
#[derive(Debug)]
pub enum Config {
2024-01-19 08:51:48 +00:00
/// The config dir doesn't exist
NoConfigDir,
2024-01-19 08:51:48 +00:00
/// We didn't find a config file in the config dir
NoConfigFileFound,
2024-01-19 08:51:48 +00:00
/// An io error happened while reading/opening it!
IoError(std::io::Error),
2024-01-19 08:51:48 +00:00
/// The given extension (via an argument) isn't known.
///
/// Occurs if the extension is neither `.json` nor `.ron` (including if there is no extension, in which case this will be `None`).
UnknownExtension(Option<String>),
2024-01-19 08:51:48 +00:00
/// Wrapper around an `Error` from `serde_json`
SerdeJsonError(serde_json::Error),
2024-01-19 08:51:48 +00:00
/// Wrapper around a `SpannedError` from `ron`
SerdeRonError(ron::error::SpannedError),
}
impl From<std::io::Error> for Config {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}
impl From<serde_json::Error> for Config {
fn from(value: serde_json::Error) -> Self {
Self::SerdeJsonError(value)
}
}
impl From<ron::error::SpannedError> for Config {
fn from(value: ron::error::SpannedError) -> Self {
Self::SerdeRonError(value)
2024-01-12 08:36:30 +00:00
}
}
}