use figment::{providers::Serialized, value, Figment, Metadata, Profile, Provider}; use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] pub struct Config { pub(crate) paths: Vec, } impl Config { pub fn from(provider: T) -> figment::error::Result { Figment::from(provider).extract() } } impl Provider for Config { fn metadata(&self) -> Metadata { Metadata::named("Tmuxr path config") } fn data(&self) -> figment::error::Result> { Serialized::defaults(Config::default()).data() } } #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] pub struct PathEntry { pub path: PathBuf, pub hidden: bool, pub recurse: Option, } impl std::str::FromStr for PathEntry { type Err = std::convert::Infallible; fn from_str(s: &str) -> Result { Ok(PathEntry { path: s.to_string().into(), ..Default::default() }) } } #[cfg(test)] mod tests { use super::*; use figment::providers::{Format, Serialized, Toml}; #[test] fn defaults() { figment::Jail::expect_with(|jail| { jail.create_file( "tmuxr.toml", r#" paths = [] "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("tmuxr.toml")) .extract()?; assert_eq!(config, Config::default()); Ok(()) }); } #[test] fn custom() { figment::Jail::expect_with(|jail| { jail.create_file( "tmuxr.toml", r#" paths = [ "/tmp/projects", { path = "/tmp/tmuxr/test/other_projects", recursive = false, hidden = true }, ] "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("tmuxr.toml")) .extract()?; assert_eq!( config, Config { paths: Vec::from([ PathEntry { path: "/tmp/tmuxr/test/project_1".into(), hidden: false, recurse: None, }, PathEntry { path: "/tmp/tmuxr/test/projects".into(), hidden: false, recurse: Some(1), } ]), } ); Ok(()) }); } }