Crate derive_from_env

Crate derive_from_env 

Source
Expand description

§derive_from_env

Extract type-safe structured configuration from environment variables using procedural derive macros.

All types are parsed using the FromStr trait, making it easy to use with any type that implements it - including your own custom types.

§Quick Start

use derive_from_env::FromEnv;

#[derive(FromEnv)]
struct Config {
    database_url: String,
    #[from_env(default = "8080")]
    port: u16,
    debug: Option<bool>,
}

// Reads from DATABASE_URL, PORT, DEBUG environment variables
let config = Config::from_env().unwrap();

§Field Attributes

The #[from_env(...)] attribute supports the following options:

AttributeDescription
default = "value"Fallback value when env var is not set
var = "NAME"Use exact env var name (ignores prefix)
rename = "name"Override field name (respects prefix)
flattenMark field as nested struct
no_prefixDon’t add field name to prefix chain (use with flatten)

§Struct Attributes

AttributeDescription
prefix = "PREFIX_"Prefix for all env vars in the struct

§Nested Structs

Use #[from_env(flatten)] to embed nested configuration structs:

use derive_from_env::FromEnv;

#[derive(FromEnv)]
struct DatabaseConfig {
    host: String,
    #[from_env(default = "5432")]
    port: u16,
}

#[derive(FromEnv)]
#[from_env(prefix = "APP_")]
struct Config {
    #[from_env(flatten)]
    database: DatabaseConfig,  // Reads APP_DATABASE_HOST, APP_DATABASE_PORT
}

§Custom Types

Any type implementing FromStr works automatically:

use std::str::FromStr;
use derive_from_env::FromEnv;

#[derive(Debug, PartialEq)]
enum LogLevel { Debug, Info, Warn, Error }

impl FromStr for LogLevel {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_lowercase().as_str() {
            "debug" => Ok(LogLevel::Debug),
            "info" => Ok(LogLevel::Info),
            "warn" => Ok(LogLevel::Warn),
            "error" => Ok(LogLevel::Error),
            _ => Err(format!("unknown log level: {}", s)),
        }
    }
}

#[derive(FromEnv)]
struct Config {
    log_level: LogLevel,  // No special attribute needed!
}

§Error Handling

The [from_env()] method returns Result<Self, FromEnvError>:

use derive_from_env::{FromEnv, FromEnvError};

#[derive(FromEnv)]
struct Config {
    port: u16,
}

match Config::from_env() {
    Ok(config) => println!("Port: {}", config.port),
    Err(FromEnvError::MissingEnvVar { var_name }) => {
        eprintln!("Missing: {}", var_name);
    }
    Err(FromEnvError::ParsingFailure { var_name, expected_type }) => {
        eprintln!("Failed to parse {} as {}", var_name, expected_type);
    }
}

Enums§

FromEnvError

Derive Macros§

FromEnv