use byte_unit::Byte; use figment::{ error::Result, providers::{Env, Format, Serialized, Toml}, value::{Dict, Map}, Figment, Metadata, Profile, Provider, }; use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] pub struct Config { pub quota: Byte, pub pool_name: String, pub mountpoint: PathBuf, } impl Default for Config { fn default() -> Self { Config { quota: 16_000_000_000u64.into(), pool_name: String::from("pool"), mountpoint: PathBuf::from("/srv"), } } } impl Config { pub fn from(provider: T) -> Result { Figment::from(provider).extract() } pub fn figment() -> Figment { Figment::from(Config::default()) .merge(Toml::file(Env::var_or("ZFS_CONFIG", "ZFS.toml")).nested()) .merge(Env::prefixed("ZFS_").global()) } } impl Provider for Config { fn metadata(&self) -> Metadata { Metadata::named("ZFS Config") } fn data(&self) -> Result> { Serialized::defaults(Config::default()).data() } } #[cfg(test)] mod tests { use std::path::PathBuf; use figment::providers::{Format, Serialized, Toml}; use super::*; #[test] fn defaults() { figment::Jail::expect_with(|jail| { jail.create_file( "Config.toml", r#" quota = "16G" pool_name = "pool" mountpoint = "/srv" "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("Config.toml")) .extract()?; assert_eq!(config, Config::default()); Ok(()) }); } #[test] fn quota_unit() { figment::Jail::expect_with(|jail| { jail.create_file( "Config.toml", r#" quota = "8G" pool_name = "fool" mountpoint = "/mnt" "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("Config.toml")) .extract()?; assert_eq!( config, Config { quota: 8_000_000_000u64.into(), pool_name: String::from("fool"), mountpoint: PathBuf::from("/mnt"), } ); Ok(()) }); } #[test] fn quota_u64() { figment::Jail::expect_with(|jail| { jail.create_file( "Config.toml", r#" quota = 42000000 pool_name = "fool" mountpoint = "/mnt" "#, )?; let config: Config = Figment::from(Serialized::defaults(Config::default())) .merge(Toml::file("Config.toml")) .extract()?; assert_eq!( config, Config { quota: 42_000_000u64.into(), pool_name: String::from("fool"), mountpoint: PathBuf::from("/mnt"), } ); Ok(()) }); } }