use crate::{finder, logging, paths, Error, Result}; use figment::{providers::Serialized, value, Figment, Metadata, Profile, Provider}; use serde::{Deserialize, Serialize}; #[derive(Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(default)] pub struct Config { #[serde(flatten)] pub paths: paths::Config, pub finder: finder::Config, pub logging: logging::Config, } impl Config { pub fn extract(provider: T) -> figment::error::Result { Figment::from(provider).extract() } } impl Provider for Config { fn metadata(&self) -> Metadata { Metadata::named("Tmuxr directory config") } fn data(&self) -> figment::error::Result> { Serialized::defaults(self).data() } } impl TryFrom for Config { type Error = Error; fn try_from(value: Figment) -> Result { value.extract().map_err(Into::into) } } #[cfg(test)] mod tests { use super::*; use figment::providers::{Format, Serialized, Toml}; #[test] fn test_extract() { figment::Jail::expect_with(|jail| { jail.create_file( "tmuxr.toml", r#" paths = [ "/path/to/projects", { path = "/path/to/other_projects", recurse = 1, hidden = true }, { path = "/path/to/another_project", recurse = 0 }, ] [finder] program = "fzf" args = ["-0", "-1", "--preview='cat'"] [logging] level = "warn" path = "/path/to/log_file" "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("tmuxr.toml")) .extract()?; assert_eq!( config, Config { paths: paths::Config { paths: Vec::from([ paths::PathEntry { path: "/path/to/projects".into(), hidden: false, recurse: None, }, paths::PathEntry { path: "/path/to/other_projects".into(), hidden: true, recurse: Some(1), }, paths::PathEntry { path: "/path/to/another_project".into(), hidden: false, recurse: Some(0), }, ]), }, finder: finder::Config { program: "fzf".into(), args: vec!["-0".into(), "-1".into(), "--preview='cat'".into()], }, logging: logging::Config { stdout: None, level: Some(logging::Level::WARN), path: "/path/to/log_file".into() }, } ); Ok(()) }); } }