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

Loading

The load feature adds strict filesystem loading. Parsing itself never reads files.

Cascades

load_cascade(directory, mode) reads, in order:

  1. .env
  2. .env.local
  3. .env.{mode}
  4. .env.{mode}.local

A missing cascade file is skipped. A file that exists but cannot be read, decoded as UTF-8 or parsed invalidates the whole load. Later files override earlier files by effective key.

load_files(paths, dialect) reads an explicit ordered list. Every listed file must exist.

Environment data

LoadedEnvironment stores:

  • final values, sorted by key;
  • shared-file origins with path, value span and line;
  • raw winning tokens for contextual resolution;
  • optional reports for entries, overrides, repeats and skipped declarations.

The default profile keeps values, origins and raw tokens. Reports are off.

use adotenv::load::load_cascade;

let loaded = load_cascade("/srv/my-app", "production")?;
assert_eq!(loaded.get("PORT"), Some("8080"));

let origin = loaded.origin("PORT").unwrap();
println!("{}:{}", origin.path().display(), origin.line());

Values and report views borrow the environment:

get(key)                 Option<&str>
values()                 Iterator<Item = (&str, &str)>
origin(key)              Option<LoadOrigin<'_>>
entries()                Iterator<Item = LoadedEntry<'_>>
overrides()              Iterator<Item = LoadedOverride<'_>>
repeated()               Iterator<Item = LoadRepeated<'_>>
skipped()                Iterator<Item = LoadSkipped<'_>>
into_values()            LoadedValues

LoadOrigin<'_> exposes path(), span() and line(). Entry, override, repeat and skipped views expose accessors rather than public fields.

Options

LoadOptions::new(dialect) is the default. LoadOptions::full(dialect) enables all reports. Builders control each group:

BuilderEffect
with_raw_tokens(false)Drop raw tokens; resolve_contextual returns an error
with_reports(false)Leave report iterators empty
with_origins(false)Drop final origins and override reports

With reports enabled, entry records share keys and values with the final value table. Reports do not duplicate final values.

Resolution

resolve_contextual reconstructs each winning raw token, reparses it with the load dialect and resolves references. Quote, escape and dialect context survive the merge. It requires raw-token retention.

resolve_decoded treats every final value as unquoted decoded text. It requires whole-file resolution scope.

Both methods return ResolvedEnvironment. Origins are available through origin(key). Command substitution remains literal unless a caller callback is provided through the document resolver.

Values only

load_cascade_values and load_values retain only final strings. They use the same projection path as core parse_values and do not keep origins, raw tokens, reports or a lossless document.

use adotenv::{load::load_cascade_values, Dialect};

let values = load_cascade_values("/srv/my-app", "production")?;
assert_eq!(values.get("PORT"), Some("8080"));
Ok::<(), Box<dyn std::error::Error>>(())

Errors

LoadError distinguishes:

  • I/O failure with path and OS error;
  • invalid UTF-8;
  • the first syntax or policy error with path and diagnostic;
  • an invalid mode name.

Mode names may not contain path separators, . or ...

Memory

Measured on a release build with one 65,536-entry file:

ProfilePeakRetained
Default47.7 MB28.0 MB
LoadOptions::full57.4 MB37.7 MB
Values only11.2 MB10.0 MB

The default loader keeps one record per key for its value, origin and raw token. Budgets and the full benchmark method are in performance.md.