Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment variables

Requires the env Cargo feature, which is enabled by default.

Not supported for enums.

Settings can also inherit values from environment variables via the #[setting(env)] attribute field. When using this, variables take the highest precedence, and are merged as the last layer.

#![allow(unused)]
fn main() {
#[derive(Config)]
struct AppConfig {
	#[setting(default = 3000, env = "PORT")]
	pub port: usize,
}
}

Container prefixes

If you’d prefer to not define env for every setting, you can instead define a prefix on the containing struct using the #[setting(env_prefix)] attribute field. This will define an environment variable for all direct fields in the struct, in the format of “env prefix + field name” in UPPER_SNAKE_CASE.

For example, the environment variable below for port is now APP_PORT.

#![allow(unused)]
fn main() {
#[derive(Config)]
#[config(env_prefix = "APP_")]
struct AppConfig {
	#[setting(default = 3000)]
	pub port: usize,
}
}

Nested prefixes

Since env_prefix only applies to direct fields and not for nested/children structs, you’ll need to define env_prefix for each struct, and manually set the prefixes. Schematic does not concatenate the prefixes between parent and child.

#![allow(unused)]
fn main() {
#[derive(Config)]
#[config(env_prefix = "APP_SERVER_")]
struct AppServerConfig {
	// ...
}

#[derive(Config)]
#[config(env_prefix = "APP_")]
struct AppConfig {
	#[setting(nested)]
	pub server: AppServerConfig,
}
}

Parsing values

We also support parsing environment variables into the required type. For example, the variable may be a comma separated list of values, or a JSON string.

The #[setting(parse_env)] attribute field can be used, which requires a path to a function to handle the parsing, and receives the variable value as a single argument.

#![allow(unused)]
fn main() {
#[derive(Config)]
struct AppConfig {
	#[setting(env = "ALLOWED_HOSTS", parse_env = schematic::env::split_comma)]
	pub allowed_hosts: Vec<String>,
}
}

We provide a handful of built-in parsing functions in the env module.

Parse handler function

You can also define your own function for parsing values out of environment variables.

When defining a custom parse_env function, the variable value is passed as the 1st argument. A None value can be returned, which will fallback to the previous or default value.

#![allow(unused)]
fn main() {
pub fn custom_parse(var: String) -> ParseEnvResult<ReturnValue> {
	do_parse()
		.map(|v| Some(v))
		.map_err(|e| HandlerError::new(e.to_string()))
}

#[derive(Config)]
struct ExampleConfig {
	#[setting(env = "FIELD", parse_env = custom_parse)]
	pub field: String,
}
}