Expand description
Configuration parsing
This crate provides a configuration parsing library and associated derive macros for parsing configuration from multiple TOML files.
As a user of this crate, you will typically define a set of structs, enums
and ‘atomic’ values that represent individual configuration settings. To
these you then apply the Configurable and ConfigurableAtomic derives.
The root of the configuration tree is represented by the RootConfig type,
which is a Configurable struct that holds the configuration for the entire
application, but has an additional RootConfig::load method that loads
the configuration from TOML files.
use statime_config::{Configurable, ConfigurableAtomic, RootConfig, SystemConfigSetting};
/// The root configuration needs to be a [`Configurable`] struct with [`RootConfig`]
/// implemented, which is used to load the configuration from TOML files.
/// It also needs to contain information which can identify whether and which
/// system configuration is to be used when loading the configuration.
#[derive(Debug, Clone, PartialEq, Eq, Configurable)]
pub struct Config {
/// Whether to use the system configuration files, note the default
/// attribute calls Default::default()
#[config(default)]
pub use_system_config: UseSystemConfig,
/// This section has no default value, if any value within it is not
/// specified and has no default, that will be an error.
pub observability: ObservabilityConfig,
}
impl RootConfig for Config {
fn use_system_config(partial: &Self::Partial) -> SystemConfigSetting {
match partial.use_system_config.clone().into_option() {
Some(UseSystemConfig::Enabled(false)) => SystemConfigSetting::None,
Some(UseSystemConfig::Enabled(true)) => SystemConfigSetting::DefaultPath(UseSystemConfig::DEFAULT_SYSTEM_CONFIG.into()),
Some(UseSystemConfig::Directory(path)) => SystemConfigSetting::UserSpecifiedPath(path),
None => SystemConfigSetting::Unset,
}
}
}
/// Only the Configurable derive is needed here, as this is not the root struct.
#[derive(Debug, Clone, PartialEq, Eq, Configurable)]
pub struct ObservabilityConfig {
/// Example of using a custom enum as an atomic value, note how the
/// default can also be any expression that evaluates to the type of
/// the field.
#[config(default = LogLevel::Info)]
pub level: LogLevel,
}
/// Example of a custom enum that is used as an atomic value, by deriving
/// the ConfigurableAtomic trait.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ConfigurableAtomic)]
#[serde(rename_all = "kebab-case")]
pub enum LogLevel {
Debug,
Info,
Warn,
Error,
}
/// Which system configuration to layer underneath the main configuration, if
/// any.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ConfigurableAtomic)]
#[serde(untagged)]
pub enum UseSystemConfig {
/// `true` reads the fragments supplied by the distribution, `false` uses no
/// system configuration at all.
Enabled(bool),
/// A directory to read the fragments from, instead of the default one.
Directory(PathBuf),
}
impl UseSystemConfig {
pub const DEFAULT_SYSTEM_CONFIG: &str = "/usr/lib/ntpd-rs/system-config";
}
impl Default for UseSystemConfig {
fn default() -> Self {
Self::Enabled(false)
}
}
fn main() {
let config = Config::load("/path/to/config.toml").unwrap();
}Modules§
Structs§
- Config
Path - A path in the tree, such as
observability.log-levelorsources[2].address. - Merge
Context - The context within the current merge operation. Generated code only ever
walks it with
MergeContext::at; the rest is the loader’s business. - NonNegative
- Origin
Id - A unique identifier that represents an origin.
- Positive
Enums§
- Config
Error - Everything that can go wrong while loading a configuration.
- Enum
Section - EnumSections are merge-able partial values within a configuration tree that have no default partial value. This is the case for enums, which may not have a default variant.
- Infinite
Or - Merge
Policy - Whether to merge by overriding values, or by rejecting any overlapping values.
- Origin
- Where a configuration file/value is coming from.
- Section
- Sections are merge-able partial values within a configuration tree.
- Setting
- An atomic merge boundary in the configuration tree.
- System
Config Setting
Traits§
- Configurable
- Relates a configuration type to how it is represented while a configuration is still being loaded.
- Configurable
Atomic - Marks a type as a value the tree does not look inside.
- IsNon
Negative - IsPositive
- Merge
- Allows the merging of two values following the merge policy in the merge context.
- Partial
Tree - Everything the loader needs of a partial configuration tree
- Partial
Value - A value in a partial configuration tree.
- Root
Config - A configuration that a document can be loaded into.
Derive Macros§
- Configurable
- Generate the partial counterpart of a configuration struct.
- Configurable
Atomic - Mark a type as a configuration value the tree does not look inside.