Structs & enums

The Config trait can be derived for structs and enums.

#![allow(unused)]
fn main() {
#[derive(Config)]
struct AppConfig {
	pub base: String,
	pub port: usize,
	pub secure: bool,
	pub allowed_hosts: Vec<String>,
}

#[derive(Config)]
enum Host {
	Local,
	Remote(HostConfig),
}
}

Enum caveats

Config can only be derived for enums with tuple or unit variants, but not struct/named variants. Why not struct variants? Because with this pattern, the enum acts like a union type. This also allows for Config functionality, like partials, merging, and validation, to be applied to the contents of each variant.

If you’d like to support unit-only enums, you can use the ConfigEnum trait instead.

Attribute fields

The following fields are supported for the #[config] container attribute:

  • allow_unknown_fields - Removes the serde deny_unknown_fields from the partial struct. Defaults to false.
  • context - Sets the struct to be used as the context. Defaults to None.
  • env_prefix - Sets the prefix to use for environment variable mapping. Defaults to None.
  • serde - A nested attribute that sets tagging related fields for the partial. Defaults to None.
#![allow(unused)]
fn main() {
#[derive(Config)]
#[config(allow_unknown_fields, env_prefix = "EXAMPLE_")]
struct ExampleConfig {
	// ...
}
}

And the following for serde compatibility:

  • rename
  • rename_all - Defaults to camelCase.

Serde support

By default the Config macro will apply the following #[serde] to the partial struct. The default and deny_unknown_fields ensure proper parsing and layer merging.

#![allow(unused)]
fn main() {
#[serde(default, deny_unknown_fields, rename_all = "camelCase")]
}

However, the deny_unknown_fields and rename_all fields can be customized, and we also support the rename field, both via the top-level #[config] attribute.

#![allow(unused)]
fn main() {
#[derive(Config)]
#[config(allow_unknown_fields, rename = "ExampleConfig", rename_all = "snake_case")]
struct Example {
	// ...
}
}

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.