Configuration
Requires the
config
Cargo feature, which is enabled by default.
The primary feature of Schematic is a layered serde-driven configuration solution, and is powered
through the Config
and ConfigEnum
traits, and their
associated derive macro. These macros help to generate and automate the following (when applicable):
- Generates a partial implementation, with all field values wrapped in
Option
. - Provides default value and environment variable handling.
- Implements merging and validation logic.
- Models a schema (when
schema
Cargo feature enabled). - And other minor features, like context & metadata.
The struct or enum that derives Config
represents the final state, after all
partial layers have been merged, and default and environment variable values have
been applied. This means that all fields (settings) should not be wrapped in Option
, unless the
setting is truly optional (think nullable in the config file).
#![allow(unused)] fn main() { #[derive(Config)] struct ExampleConfig { pub number: usize, pub string: String, pub boolean: bool, pub array: Vec<String>, pub optional: Option<String>, } }
This pattern provides the optimal developer experience, as you can reference the settings as-is, without having to unwrap them, or use
match
orif-let
statements!
Usage
Define a struct or enum and derive the Config
trait. Fields within the struct
(known as settings) can be annotated with the #[setting]
attribute to provide
additional functionality.
#![allow(unused)] fn main() { use schematic::Config; #[derive(Config)] struct AppConfig { #[setting(default = 3000, env = "PORT")] pub port: usize, #[setting(default = true)] pub secure: bool, #[setting(default = vec!["localhost".into()])] pub allowed_hosts: Vec<String>, } }
Loading sources
When all of your structs and enums have been defined, you can then load, parse, merge, and validate a configuration from one or many sources. A source is either a file path, secure URL, or inline code string.
Begin by importing the
ConfigLoader
struct and
initializing it with the Config
type you want to load.
#![allow(unused)] fn main() { use schematic::ConfigLoader; let loader = ConfigLoader::<AppConfig>::new(); }
From here, you can feed it sources to load. For file paths, use the
ConfigLoader::file()
or
ConfigLoader::file_optional()
methods. For URLs, use the
ConfigLoader::url()
method (requires the url
Cargo feature, which is on by default). For inline code, use the
ConfigLoader::code()
method, which requires an explicit format.
#![allow(unused)] fn main() { use schematic::Format; loader.code("secure: false", Format::Yaml)?; loader.file("path/to/config.yml")?; loader.url("https://ordomain.com/to/config.yaml")?; }
The format for files and URLs are derived from the trailing extension.
And lastly call the
ConfigLoader::load()
method to generate the final configuration. This methods returns a result, which includes the final
configuration, as well as all of the partial layers that were loaded.
#![allow(unused)] fn main() { let result = loader.load()?; result.config; // AppConfig result.layers; // Vec<Layer<PartialAppConfig>> }
Automatic schemas
When the schema
Cargo feature is enabled, the
Schematic
trait will be
automatically implemented for all types that implement
Config
and
ConfigEnum
. You do not and
should not derive both of these together.
#![allow(unused)] fn main() { // Correct #[derive(Config)] struct AppConfig {} // Incorrect #[derive(Config, Schematic)] struct AppConfig {} }
Supported source formats
Schematic is powered entirely by serde, and supports the following formats:
- JSON - Uses
serde_json
and requires thejson
Cargo feature. - Pkl (experimental) - Uses
rpkl
and requires thepkl
Cargo feature. - TOML - Uses
toml
and requires thetoml
Cargo feature. - YAML - Uses
serde_yaml
and requires theyaml
Cargo feature.
Cargo features
The following Cargo features are available:
config
(default) - Enables configuration support (all the above stuff).env
(default) - Enables environment variables for settings.extends
(default) - Enables configs to extend other configs.json
- Enables JSON.pkl
- Enables Pkl.toml
- Enables TOML.tracing
- Wrap generated code in tracing instrumentations.url
- Enables loading, extending, and parsing configs from URLs.validate
(default) - Enables setting value validation.yaml
- Enables YAML.