pub struct Env {
    pub profile: Profile,
    /* private fields */
}
Available on crate feature env only.
Expand description

A Provider that sources its values from environment variables.

All key-lookups and comparisons are case insensitive, facilitated by the UncasedStr and Uncased types. Environment variable names are converted to lowercase before being emitted as key paths in the provided data. Environment variable values can contain structured data, parsed as a Value, with syntax resembling TOML:

  • Bool: true, false (e.g, APP_VAR=true)
  • Num::F64: any float containing .: (e.g, APP_VAR=1.2, APP_VAR=-0.002)
  • Num::USize: any unsigned integer (e.g, APP_VAR=10)
  • Num::Isize: any negative integer (e.g, APP_VAR=-10)
  • Array: delimited by [] (e.g, APP_VAR=[true, 1.0, -1])
  • Dict: in the form {key=value} (e.g, APP_VAR={key="value",num=10})
  • String: delimited by " (e.g, APP_VAR=\"hi\")
  • String: anything else (e.g, APP_VAR=hi, APP_VAR=[hi)

Additionally, keys and strings delimited with " can contain the following escaped characters:

\b         - backspace       (U+0008)
\t         - tab             (U+0009)
\n         - linefeed        (U+000A)
\f         - form feed       (U+000C)
\r         - carriage return (U+000D)
\"         - quote           (U+0022)
\\         - backslash       (U+005C)
\uXXXX     - unicode         (U+XXXX)
\UXXXXXXXX - unicode         (U+XXXXXXXX)

For example:

APP_VAR=\"hello\\nthere\"  => (what in Rust is) "hello\nthere"
APP_VAR=\"hi\\u1234there\" => (what in Rust is) "hi\u{1234}there"
APP_VAR=\"abc\\td\\n\"     => (what in Rust is) "abc\td\n"

APP_VAR={\"key\\nkey\"=123}`)
APP_VAR={\"key.key\"=123}`)

Undelimited strings, or strings with invalid escape sequences, are interpreted exactly as written without any escaping.

Key Paths (nesting)

Because environment variables names are emitted as key paths in the provided data, a nested dictionary is created for every component of the name delimited by ., each a parent of the next, with the leaf mapping to environment variable Value. For example, the environment variable a.b.c=3 creates the mapping a -> b -> c -> 3 in the emitted data.

Environment variable names cannot typically contain the . character, but another character can be used in its place by replacing that character in the name with . with Env::map(). The Env::split() method is a convenience method that does exactly this.

Provider Details

  • Profile

    This provider does not set a profile.

  • Metadata

    This provider is named environment variable(s). It does not specify a Source. Interpolation makes path parts uppercase and delimited with a ..

  • Data

    The data emitted by this provider is single-level dictionary with the keys and values returned by Env::iter(), which reads from the currently set environment variables and is customizable via the various inherent methods. The dictionary is emitted to the profile profile, configurable via Env::profile().

Fields

profile: Profile

The profile config data will be emitted to. Defaults to Profile::Default.

Implementations

Constructs and Env provider that does not filter or map any environment variables.

use serde::Deserialize;
use figment::{Figment, Jail, providers::Env};

#[derive(Debug, PartialEq, Deserialize)]
struct Config {
    numbers: Vec<usize>,
    app_bar: String,
}

Jail::expect_with(|jail| {
    jail.set_env("NUMBERS", "[1, 2, 3]");
    jail.set_env("APP_BAR", "hi");

    let config: Config = Figment::from(Env::raw()).extract()?;
    assert_eq!(config, Config {
        numbers: vec![1, 2, 3],
        app_bar: "hi".into(),
    });

    Ok(())
});

Return an Env provider that filters environment variables to those with the prefix prefix and maps to one without the prefix.

use serde::Deserialize;
use figment::{Figment, Jail, providers::Env};

#[derive(Debug, PartialEq, Deserialize)]
struct Config {
    foo: usize,
    bar: String,
}

Jail::expect_with(|jail| {
    jail.set_env("APP_FOO", 100);
    jail.set_env("APP_BAR", "hi");

    let config: Config = Figment::from(Env::prefixed("APP_")).extract()?;
    assert_eq!(config, Config { foo: 100, bar: "hi".into() });

    Ok(())
});

Applys an additional filter to the keys of environment variables being considered.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("FOO_FOO", 100);
    jail.set_env("BAR_BAR", "hi");
    jail.set_env("foobar", "hi");

    // We'll be left with `FOO_FOO=100` and `foobar=hi`.
    let env = Env::raw().filter(|k| k.starts_with("foo"));
    assert_eq!(env.iter().count(), 2);

    // Filters chain, like iterator adapters. `FOO_FOO=100` remains.
    let env = env.filter(|k| k.as_str().contains('_'));
    assert_eq!(env.iter().count(), 1);

    Ok(())
});

Applys an additional mapping to the keys of environment variables being considered.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("FOO_FOO", 100);
    jail.set_env("BAR_FOO", "hi");
    jail.set_env("foobar", "hi");

    // This is like `prefixed("foo_")` without the filtering.
    let env = Env::raw().map(|k| match k.starts_with("foo_") {
        true => k["foo_".len()..].into(),
        false => k.into()
    });

    // We now have `FOO=100`, `BAR_FOO=hi`, and `bar=hi`.
    assert_eq!(env.clone().filter(|k| k == "foo").iter().count(), 1);

    // Mappings chain, like iterator adapters.
    let env = env.map(|k| match k.starts_with("bar_") {
        true => k["bar_".len()..].into(),
        false => k.into()
    });

    // We now have `FOO=100`, `FOO=hi`, and `bar=hi`.
    assert_eq!(env.filter(|k| k == "foo").iter().count(), 2);
    Ok(())
});

Splits each environment variable key at pattern, creating nested dictionaries for each split. Specifically, nested dictionaries are created for components delimited by pattern in the environment variable string (3 in A_B_C if pattern is _), each dictionary mapping to its parent.

This is equivalent to: self.map(|key| key.replace(pattern, ".")).

Example
use serde::Deserialize;
use figment::{Figment, Jail, util::map, value::Dict, providers::Env};

#[derive(Debug, PartialEq, Deserialize)]
struct Foo {
    key: usize,
}

#[derive(Debug, PartialEq, Deserialize)]
struct Config {
    foo: Foo,
    map: Dict,
}

Jail::expect_with(|jail| {
    // Without splitting: using structured data.
    jail.set_env("APP_FOO", "{key=10}");
    jail.set_env("APP_MAP", "{one=1,two=2.0}");

    let config: Config = Figment::from(Env::prefixed("APP_")).extract()?;
    assert_eq!(config, Config {
        foo: Foo { key: 10 },
        map: map!["one".into() => 1u8.into(), "two".into() => 2.0.into()],
    });

    // With splitting.
    jail.set_env("APP_FOO_KEY", 20);
    jail.set_env("APP_MAP_ONE", "1.0");
    jail.set_env("APP_MAP_TWO", "dos");

    let config: Config = Figment::new()
        .merge(Env::prefixed("APP_").split("_"))
        .extract()?;

    assert_eq!(config, Config {
        foo: Foo { key: 20 },
        map: map!["one".into() => 1.0.into(), "two".into() => "dos".into()],
    });

    Ok(())
});

Filters out all environment variable keys contained in keys.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("FOO_FOO", 1);
    jail.set_env("FOO_BAR", 2);
    jail.set_env("FOO_BAZ", 3);
    jail.set_env("FOO_BAM", 4);

    let env = Env::prefixed("FOO_").ignore(&["bar", "baz"]);
    assert_eq!(env.clone().iter().count(), 2);

    // Ignores chain.
    let env = env.ignore(&["bam"]);
    assert_eq!(env.iter().count(), 1);
    Ok(())
});

Filters out all environment variables keys not contained in keys.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("FOO_FOO", 1);
    jail.set_env("FOO_BAR", 2);
    jail.set_env("FOO_BAZ_BOB", 3);
    jail.set_env("FOO_BAM_BOP", 4);

    let env = Env::prefixed("FOO_").only(&["bar", "baz_bob", "zoo"]);
    assert_eq!(env.iter().count(), 2);

    jail.set_env("FOO_ZOO", 5);
    assert_eq!(env.iter().count(), 3);

    let env = Env::prefixed("FOO_").split("_");
    assert_eq!(env.clone().only(&["bar", "baz.bob"]).iter().count(), 2);
    assert_eq!(env.clone().only(&["bar", "bam_bop"]).iter().count(), 1);

    Ok(())
});

Returns an iterator over all of the environment variable (key, value) pairs that will be considered by self. The order is not specified.

Keys are lower-cased with leading and trailing whitespace removed. Empty keys, or partially empty keys, are not emitted.

Any non-Unicode sequences in values are replaced with U+FFFD REPLACEMENT CHARACTER. Values are otherwise unmodified.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("FOO_B", 2);
    jail.set_env("FOO_A", 1);
    jail.set_env("FOO_C", 3);

    let env = Env::prefixed("FOO_");
    let mut pairs: Vec<_> = env.iter().collect();
    pairs.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));

    assert_eq!(pairs.len(), 3);
    assert_eq!(pairs[0], ("a".into(), "1".into()));
    assert_eq!(pairs[1], ("b".into(), "2".into()));
    assert_eq!(pairs[2], ("c".into(), "3".into()));

    jail.set_env("FOO_D", 4);
    let mut pairs: Vec<_> = env.iter().collect();
    pairs.sort_by(|(k1, _), (k2, _)| k1.cmp(k2));

    assert_eq!(pairs.len(), 4);
    assert_eq!(pairs[3], ("d".into(), "4".into()));

    Ok(())
});

Sets the profile config data will be emitted to.

use figment::{Profile, providers::Env};

let env = Env::raw();
assert_eq!(env.profile, Profile::Default);

let env = env.profile("debug");
assert_eq!(env.profile, Profile::from("debug"));

Sets the profile config data will be emitted to to global.

use figment::{Profile, providers::Env};

let env = Env::raw();
assert_eq!(env.profile, Profile::Default);

let env = env.global();
assert_eq!(env.profile, Profile::Global);

A convenience method to retrieve the value for an environment variable with name name. Retrieval is case-insensitive.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("TESTING", 123);
    assert_eq!(Env::var("testing"), Some("123".to_string()));
    Ok(())
});

A convenience method to retrieve the value for an environment variable with name name or a default default if one is not set. Retrieval is case-insensitive.

use figment::{Jail, providers::Env};

Jail::expect_with(|jail| {
    jail.set_env("TESTING", 123);
    assert_eq!(Env::var_or("testing", "whoops"), "123");
    assert_eq!(Env::var_or("hi", "whoops"), "whoops");
    Ok(())
});

Trait Implementations

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Formats the value using the given formatter. Read more
Returns the Metadata for this provider, identifying itself and its configuration sources. Read more
Returns the configuration data.
Optionally returns a profile to set on the Figment this provider is merged into. The profile is only set if self is merged. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Converts self into a collection.
Should always be Self
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more