Smart Schema-driven Layered Configuration System
smart-config is a schema-driven layered configuration system with support of multiple configuration formats.
The task solved by the library is merging configuration input from a variety of prioritized sources (JSON and YAML files, env variables, command-line args etc.) and converting this input to strongly typed representation (i.e., config structs or enums). As with other config systems, config input follows the JSON object model, with each value enriched with its origin (e.g., a path in a specific JSON file, or a specific env var). This allows attributing errors during deserialization.
The defining feature of smart-config is its schema-driven design. Each config type has associated metadata
defined with the help of the derive macros.
Metadata includes a variety of info extracted from the config type:
- Parameter info: name (including aliases and renaming), help (extracted from doc comments), type, deserializer for the param etc.
- Nested / flattened configurations.
Multiple configurations are collected into a global schema. Each configuration is mounted at a specific path.
E.g., if a large app has an HTTP server component, it may be mounted at api.http. Multiple config types may be mounted
at the same path (e.g., flattened configs); conversely, a single config type may be mounted at multiple places.
This information provides rich human-readable info about configs. It also assists when preprocessing and merging config inputs. For example, env vars are a flat string -> string map; with the help of a schema, it's possible to:
- Correctly nest vars (e.g., transform the
API_HTTP_PORTvar into aportvar insidehttpobject insideapiobject) - Transform value types from strings to expected types.
Features
- Rich, self-documenting configuration schema.
- Utilizes the schema to enrich configuration sources and intelligently merge them.
- Doesn't require a god object uniting all configs in the app; they may be dynamically collected and deserialized inside relevant components.
- Supports lazy parsing for complex / multi-component apps (only the used configs are parsed; other configs are not required).
- Supports multiple configuration formats and programmable source priorities (e.g.,
base.yml+ overrides from theoverrides/dir in the alphabetic order + env vars). - Rich and complete deserialization errors including locations and value origins.
Usage
Add this to your Crate.toml:
[]
= "0.4.0-pre"
Declaring configurations
use ;
use ;
use ;
/// Configuration with type params of several types.
// derive according to default values for params
Testing config deserialization
use ;
let input = config!;
// `test_complete` ensures that all params are mentioned in the input
let config = .unwrap;
assert_eq!;
assert_eq!;
Deserializing config
use ;
let mut schema = default;
schema.insert;
// Assume we use two config sources: a YAML file and env vars,
// the latter having higher priority.
let yaml = r"
test:
port: 4000
name: app
";
let yaml = new?;
let env = from_iter;
// Add both sources to a repo.
let repo = new.with.with;
// Get the parser for the config.
let parser = repo.?;
let config = parser.parse?;
assert_eq!; // from the env var
assert_eq!; // from YAML
assert!; // from the default value
Ok
See crate docs for more examples.
Alternatives and similar tools
configandfigmentare multi-layered configuration libraries. They provide a similar scope of functionality, missing some features (e.g., auto-generated docs, smart handling of env vars, extended error reporting, smart coercions etc.).envyprovidesserde-based parsing from env vars.
License
Distributed under the terms of either
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.