Configuration Binding
The preferred way to read related configuration values is using the options pattern. For example, to read the following configuration values:
{
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
}
Create the following PositionOptions
struct:
#[derive(Default)]
pub struct PositionOptions {
pub title: String,
pub name: String,
}
An options struct:
- must be public.
- should implement the
Default
trait; otherwise a customOptionsFactory
is required. - binds public read-write fields.
The following code:
- calls
ConfigurationBinder::bind
to bind thePositionOptions
class to the"Position"
section. - displays the
Position
configuration data. - requires the binder feature to be enabled
- which transitively enables the serde feature
use config::*;
#[derive(Default, Deserialize)]
#[serde(rename_all(deserialize = "PascalCase"))]
pub struct PositionOptions {
pub title: String,
pub name: String,
}
pub TestModel<'a> {
config: &'a dyn Configuration
}
impl<'a> TestModel<'a> {
pub new(config: &dyn Configuration) -> Self {
Self { config }
}
pub get(&self) -> String {
let mut options = PositionOptions::default();
let section = self.config.section("Position").bind(&mut options);
format!("Title: {}\nName: {}", options.title, options.name)
}
}
ConfigurationBinder::reify
binds and returns the specified type. ConfigurationBinder::reify
may be more convenient than using ConfigurationBinder::bind
. The following code shows how to use ConfigurationBinder::reify
with the PositionOptions
struct:
use config::*;
pub TestModel<'a> {
config: &'a dyn Configuration
}
impl<'a> TestModel<'a> {
pub new(config: &dyn Configuration) -> Self {
Self { config }
}
pub get(&self) -> String {
let options: PositionOptions = self.config.section("Position").reify();
format!("Title: {}\nName: {}", options.title, options.name)
}
}