mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-07-01 10:41:03 +02:00
refactor(config): use universal-config
crate.
XML config is not supported.
This commit is contained in:
parent
01a36a9476
commit
ecdd71a43d
4 changed files with 112 additions and 176 deletions
|
@ -1,18 +1,12 @@
|
|||
use super::{BarPosition, Config, MonitorConfig};
|
||||
use color_eyre::eyre::Result;
|
||||
use color_eyre::eyre::{ContextCompat, WrapErr};
|
||||
use color_eyre::{Help, Report};
|
||||
use dirs::config_dir;
|
||||
use gtk::Orientation;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{env, fs};
|
||||
use tracing::instrument;
|
||||
|
||||
// Manually implement for better untagged enum error handling:
|
||||
// currently open pr: https://github.com/serde-rs/serde/pull/1544
|
||||
impl<'de> Deserialize<'de> for MonitorConfig {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
|
@ -62,87 +56,3 @@ impl BarPosition {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Attempts to load the config file from file,
|
||||
/// parse it and return a new instance of `Self`.
|
||||
pub fn load() -> Result<Self> {
|
||||
let config_path = env::var("IRONBAR_CONFIG").map_or_else(
|
||||
|_| Self::try_find_config(),
|
||||
|config_path| {
|
||||
let path = PathBuf::from(config_path);
|
||||
if path.exists() {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(Report::msg(format!(
|
||||
"Specified config file does not exist: {}",
|
||||
path.display()
|
||||
))
|
||||
.note("Config file was specified using `IRONBAR_CONFIG` environment variable"))
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
Self::load_file(&config_path)
|
||||
}
|
||||
|
||||
/// Attempts to discover the location of the config file
|
||||
/// by checking each valid format's extension.
|
||||
///
|
||||
/// Returns the path of the first valid match, if any.
|
||||
#[instrument]
|
||||
fn try_find_config() -> Result<PathBuf> {
|
||||
let config_dir = config_dir().wrap_err("Failed to locate user config dir")?;
|
||||
|
||||
let extensions = vec!["json", "toml", "yaml", "yml", "corn"];
|
||||
|
||||
let file = extensions.into_iter().find_map(|extension| {
|
||||
let full_path = config_dir
|
||||
.join("ironbar")
|
||||
.join(format!("config.{extension}"));
|
||||
|
||||
if Path::exists(&full_path) {
|
||||
Some(full_path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
file.map_or_else(
|
||||
|| {
|
||||
Err(Report::msg("Could not find config file")
|
||||
.suggestion("Ironbar does not include a configuration out of the box")
|
||||
.suggestion("A guide on writing a config can be found on the wiki:")
|
||||
.suggestion("https://github.com/JakeStanger/ironbar/wiki/configuration-guide"))
|
||||
},
|
||||
Ok,
|
||||
)
|
||||
}
|
||||
|
||||
/// Loads the config file at the specified path
|
||||
/// and parses it into `Self` based on its extension.
|
||||
fn load_file(path: &Path) -> Result<Self> {
|
||||
let file = fs::read(path).wrap_err("Failed to read config file")?;
|
||||
|
||||
let str = std::str::from_utf8(&file)?;
|
||||
|
||||
let extension = path
|
||||
.extension()
|
||||
.unwrap_or_default()
|
||||
.to_str()
|
||||
.unwrap_or_default();
|
||||
|
||||
match extension {
|
||||
#[cfg(feature = "config+json")]
|
||||
"json" => serde_json::from_str(str).wrap_err("Invalid JSON config"),
|
||||
#[cfg(feature = "config+toml")]
|
||||
"toml" => toml::from_str(str).wrap_err("Invalid TOML config"),
|
||||
#[cfg(feature = "config+yaml")]
|
||||
"yaml" | "yml" => serde_yaml::from_str(str).wrap_err("Invalid YAML config"),
|
||||
#[cfg(feature = "config+corn")]
|
||||
"corn" => libcorn::from_str(str).wrap_err("Invalid Corn config"),
|
||||
_ => Err(Report::msg(format!("Unsupported config type: {extension}"))
|
||||
.note("You may need to recompile with support if available")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ use tokio::task::block_in_place;
|
|||
use crate::error::ExitCode;
|
||||
use clients::wayland::{self, WaylandClient};
|
||||
use tracing::{debug, error, info};
|
||||
use universal_config::ConfigLoader;
|
||||
|
||||
const GTK_APP_ID: &str = "dev.jstanger.ironbar";
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
@ -57,13 +58,19 @@ async fn main() -> Result<()> {
|
|||
|display| display,
|
||||
);
|
||||
|
||||
let config = match Config::load() {
|
||||
let config_res = match env::var("IRONBAR_CONFIG") {
|
||||
Ok(path) => ConfigLoader::load(path),
|
||||
Err(_) => ConfigLoader::new("ironbar").find_and_load(),
|
||||
};
|
||||
|
||||
let config = match config_res {
|
||||
Ok(config) => config,
|
||||
Err(err) => {
|
||||
error!("{:?}", err);
|
||||
exit(ExitCode::Config as i32)
|
||||
}
|
||||
};
|
||||
|
||||
debug!("Loaded config file");
|
||||
|
||||
if let Err(err) = create_bars(app, &display, wayland_client, &config) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue