Skip to main content

Crate dotenv

Crate dotenv 

Source
Expand description

Loads environment variables from .env files.

§Quick start

dotenv::load()?;

Call load near the start of your program to load a .env file from the current working directory.

§Precedence

  • Existing environment variables are never overwritten. A variable already set in the environment takes priority over anything in .env.
  • First declaration wins in .env. If the same key appears multiple times, only the first is used.

§Supported syntax

HELLO=world
HELLO="world"
HELLO='world'
HELLO='"nested"'
HELLO=world  # inline comment
# full-line comment

§Key names

Keys may only contain ASCII letters, digits, _, ., and -.

§Limitations

  • Multi-line values are not supported.
  • Variable substitution (e.g. ${FOO}) is not supported.
  • Export syntax (export KEY=value) is not supported.

§Deserializing into structs with FromEnv

This crate provides a FromEnv trait (and a #[derive(FromEnv)] proc-macro) for constructing typed structs directly from environment variables.

§Basic usage

use dotenv::FromEnv;

#[derive(FromEnv)]
struct Config {
    #[env(rename = "MY_HOST")]
    host: String,
    #[env(rename = "MY_PORT")]
    port: u16,
}

let cfg = Config::from_env().unwrap();

§Default values

Use #[env(default)] for any type that implements Default (yields the default when unset e.g. None for Option<T>, 0 for numbers, "" for String) or #[env(default = expr)] for any type:

#[derive(FromEnv)]
struct Config {
    #[env(rename = "MY_HOST")]
    host: String,
    #[env(default)]
    verbose: Option<bool>,
    #[env(default)]
    timeout: u64,
    #[env(rename = "MY_PORT", default = 8080)]
    port: u16,
}

In all cases the environment variable is checked first. The default value is only used when the variable is not set.

§Custom parsers

When the standard FromStr parsing is insufficient, provide a custom parser via #[env(with = "func")]. The function signature must be fn(&str, &str) -> Result<T, FromEnvError>:

use dotenv::{FromEnv, FromEnvError};

fn parse_port(_var: &str, val: &str) -> Result<u16, FromEnvError> {
    val.parse().map_err(|e| FromEnvError::invalid("MY_PORT", val, e))
}

#[derive(FromEnv)]
struct Config {
    #[env(rename = "MY_PORT", with = "parse_port")]
    port: u16,
}

§Nested structs

Fields whose type also implements FromEnv are automatically detected and populated as nested structs. The parent’s field name (in SCREAMING_SNAKE_CASE) is used as a prefix so that child fields are read from prefixed variable names:

#[derive(FromEnv)]
struct AppConfig {
    database: Database,
    debug: bool,       // reads DEBUG
}

#[derive(FromEnv)]
struct Database {
    url: String,       // reads DATABASE_URL
    pool_size: u32,    // reads DATABASE_POOL_SIZE
}

§Custom FromEnvValue implementations

For leaf types that need special parsing logic, implement FromEnvValue directly on your type. Types that implement FromStr get a blanket impl automatically.

§Convenience function

The function from_env lets you avoid importing the trait:

let cfg: Config = dotenv::from_env().unwrap();

Structs§

ParseError
A parse error with the line number and kind.

Enums§

Error
Errors that can occur when loading a .env file.
FromEnvError
Error returned by FromEnv::from_env.
ParseErrorKind
The specific kind of parse error.

Traits§

FromEnv
Trait for types that can be constructed from environment variables.
FromEnvAuto
Auto-dispatch trait for un-attributed #[derive(FromEnv)] fields.
FromEnvValue
Trait for converting a raw env-var string into a typed value.

Functions§

from_env
Convenience function to load a FromEnv type from environment variables.
load
Loads the .env file from the current working directory.

Derive Macros§

FromEnv