Settings
Settings are the individual fields of a Config struct or variants of a
Config enum, and can be annotated with the optional #[setting] attribute.
Third-party types
A setting that isn’t wrapped in Option falls back to Default::default() when the config provides
no value and no default value is declared, so every required setting has to
implement Default. Plenty of third-party types don’t, and being foreign, can’t be given it.
For the two we support directly, we provide a newtype that does:
| Setting | Wraps | Default | Cargo feature |
|---|---|---|---|
RegexSetting | regex::Regex | . | type_regex |
VersionSetting | semver::Version | 0.0.0 | type_semver |
#![allow(unused)]
fn main() {
use schematic::{Config, RegexSetting, VersionSetting};
#[derive(Config)]
struct AppConfig {
pub allowed: RegexSetting,
pub version: VersionSetting,
}
}
Each derefs to the type it wraps, so its methods can be called directly, and each parses from a
string, so the wrapper works without the upstream crate’s serde feature.
semver::VersionReqneeds no wrapper, as it already defaults to*. Types that are only ever optional don’t need one either, since anOptionsetting defaults toNone.
Attribute fields
The following fields are supported for the #[setting] field/variant attribute:
default- Sets the default value. On an enum variant, this is a marker that takes no value, and names the variant the partial defaults to.env(struct only) - Sets the environment variable to receive a value from.env_prefix(struct only) - Overrides the environment variable prefix of the nested config this field holds. Requiresnested.exclude- Omits the field or variant from the generated schema. Has no effect without theschemaCargo feature.extend(struct only) - Enables a configuration to extend other configs.merge- Defines a function to use for merging values.nested- Marks the field as using a nestedConfig.null(enum only) - Marks the variant as representingnull, so it is never tagged.parse_env(struct only) - Parses the environment variable value using a function. Requires eitherenv, or anenv_prefixon the container.partial- Forwards attributes to the field on the partial.required- Marks the field as required. This is useful forOptiontypes that do not supportDefault, but require a value.transform- Defines a function to use for transforming values.validate- Defines a function to use for validating values.
And the following for serde compatibility:
aliasflattenrenameskipskip_deserializingskip_serializingskip_serializing_if- Only honored from#[setting], and written against the partial’sOption. The#[serde]form is left for the full type, whose field is not wrapped.untagged(enum only)
Serde support
A handful of serde attribute fields are currently supported (above) and will apply a #[serde]
attribute to the partial implementation.
#![allow(unused)]
fn main() {
#[derive(Config)]
struct Example {
#[setting(rename = "type")]
pub type_of: SomeEnum,
}
}
These values can also be applied using
#[serde], which is useful if you want to apply them to the main struct as well, and not just the partial struct. When a field is set through both, the#[setting]value wins, except foralias, where the two lists are merged.
Names are used exactly as written. There is no default casing, so a field named allowed_hosts is
parsed as allowed_hosts unless a rename or rename_all says otherwise. An explicit rename is
never re-cased by rename_all.