use figment::{providers::Serialized, value, Figment, Metadata, Profile, Provider}; use serde::{Deserialize, Serialize}; #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[serde(default)] pub struct Config { pub program: String, pub args: Vec, } impl Config { // Extract the configuration from any `Provider` pub fn extract(provider: T) -> figment::error::Result { Figment::from(provider).extract() } // Provide a default provider, a `Figment`. pub fn figment() -> Figment { Figment::from(Config::default()) } } impl Default for Config { fn default() -> Self { Self { program: "fzf".into(), args: [ "--multi", "--print-query", "-d/", "--preview-window=right,75%,<80(up,75%,border-bottom)", "--preview='sel={}; less ${sel:-{q}} 2>/dev/null'", ] .map(Into::into) .to_vec(), } } } impl Provider for Config { fn metadata(&self) -> Metadata { Metadata::named("Tmuxr finder config") } fn data(&self) -> figment::error::Result> { Serialized::defaults(Self::default()).data() } } #[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#" program = "fzf" args = ["-0", "-1", "--preview='cat'"] "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("tmuxr.toml")) .extract()?; assert_eq!( config, Config { program: "fzf".into(), args: ["-0", "-1", "--preview='cat'"].map(Into::into).to_vec(), } ); Ok(()) }); } }