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,
}
}