hyprshell_core_lib/config/
load.rs

1use crate::config;
2use crate::config::{check, Config};
3use anyhow::{bail, Context};
4use ron::extensions::Extensions;
5use ron::Options;
6use std::ffi::OsStr;
7use std::path::Path;
8use tracing::{debug, info, span, warn, Level};
9
10pub fn load_config(config_path: &Path) -> anyhow::Result<Config> {
11    let _span = span!(Level::TRACE, "load_config", path =? config_path).entered();
12    if !config_path.exists() {
13        bail!("Config file does not exist, create it using `hyprshell config generate`");
14    }
15    let config = match config_path.extension().and_then(OsStr::to_str) {
16        None | Some("ron") => {
17            let options = Options::default()
18                .with_default_extension(Extensions::IMPLICIT_SOME)
19                .with_default_extension(Extensions::UNWRAP_NEWTYPES)
20                .with_default_extension(Extensions::UNWRAP_VARIANT_NEWTYPES);
21            let file = std::fs::File::open(config_path)
22                .with_context(|| format!("Failed to open config at ({config_path:?})"))?;
23            options
24                .from_reader(file)
25                .context("Failed to read ron config")
26        }
27        Some("json") => {
28            let file = std::fs::File::open(config_path)
29                .with_context(|| format!("Failed to open config at ({config_path:?})"))?;
30            serde_json::from_reader(file).context("Failed to read json config")
31        }
32        #[cfg(feature = "toml_config")]
33        Some("toml") => {
34            use std::io::Read;
35            let mut file = std::fs::File::open(config_path)
36                .with_context(|| format!("Failed to open config at ({config_path:?})"))?;
37            let mut content = String::new();
38            file.read_to_string(&mut content)
39                .context("Failed to read toml config")?;
40            toml::from_str(&content).context("Failed to parse toml config")
41        }
42        Some(ext) => bail!("Invalid config file extension: {} (check `FEATURES: ` debug log to see enabled extensions)", ext),
43    };
44
45    let config = match config {
46        Ok(cfg) => cfg,
47        Err(err) => {
48            warn!("Failed to load config: {err:?}");
49            info!("Attempting to migrate config");
50            let migrated = config::migrate::migrate(config_path);
51            match migrated {
52                Ok(cfg) => {
53                    info!("Config migrated successfully");
54                    cfg
55                }
56                Err(err) => {
57                    warn!("Migration failed: {err:?}");
58                    bail!("Failed to load config and migration failed");
59                }
60            }
61        }
62    };
63    debug!("Loaded config");
64
65    check(&config)?;
66
67    Ok(config)
68}