| Crates.io | derive_from_env |
| lib.rs | derive_from_env |
| version | 1.0.1 |
| created_at | 2024-07-29 04:29:00.311069+00 |
| updated_at | 2026-01-03 09:51:56.258306+00 |
| description | Extract type safe structured data from environment variables with procedural derive macros |
| homepage | https://github.com/AntoineRenaud91/derive_from_env |
| repository | https://github.com/AntoineRenaud91/derive_from_env |
| max_upload_size | |
| id | 1318482 |
| size | 46,368 |
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.
[dependencies]
derive_from_env = "0.1"
use derive_from_env::FromEnv;
#[derive(FromEnv)]
struct Config {
host: String,
port: u16,
debug: bool,
}
fn main() {
// Reads from HOST, PORT, DEBUG environment variables
let config = Config::from_env().unwrap();
}
prefix = "PREFIX_"Sets a prefix for all environment variables in the struct.
#[derive(FromEnv)]
#[from_env(prefix = "MYAPP_")]
struct Config {
host: String, // Reads from MYAPP_HOST
port: u16, // Reads from MYAPP_PORT
}
default = "value"Provides a fallback value when the environment variable is not set.
#[derive(FromEnv)]
struct Config {
#[from_env(default = "localhost")]
host: String,
#[from_env(default = "8080")]
port: u16,
}
var = "NAME"Overrides the environment variable name completely. This ignores any prefix.
#[derive(FromEnv)]
#[from_env(prefix = "APP_")]
struct Config {
#[from_env(var = "DATABASE_URL")] // Uses DATABASE_URL, not APP_DATABASE_URL
db_url: String,
}
rename = "name"Renames the field for environment variable lookup, but still respects the prefix.
#[derive(FromEnv)]
#[from_env(prefix = "APP_")]
struct Config {
#[from_env(rename = "db_url")] // Uses APP_DB_URL instead of APP_DATABASE_URL
database_url: String,
}
flattenMarks a field as a nested struct. Required for any field that is itself a struct deriving FromEnv but not implementing FromStr.
#[derive(FromEnv)]
struct DatabaseConfig {
host: String,
port: u16,
}
#[derive(FromEnv)]
struct Config {
#[from_env(flatten)]
database: DatabaseConfig, // Reads from DATABASE_HOST, DATABASE_PORT
}
Struct prefixes combine when nesting structs:
#[derive(FromEnv)]
#[from_env(prefix = "SERVICE_")]
struct ServiceConfig {
host: String,
port: u16,
}
#[derive(FromEnv)]
#[from_env(prefix = "APP_")]
struct Config {
#[from_env(flatten)]
database: DatabaseConfig, // Reads from APP_DATABASE_SERVICE_HOST, APP_DATABASE_SERVICE_PORT
}
no_prefixUsed with flatten to prevent adding the field name to the prefix chain.
#[derive(FromEnv)]
#[from_env(prefix = "APP_")]
struct Config {
#[from_env(flatten, no_prefix)]
database: DatabaseConfig, // Reads from APP_HOST, APP_PORT (not APP_DATABASE_HOST)
}
All types are parsed using the FromStr trait. This includes:
i8, i16, i32, i64, u8, u16, u32, u64, f32, f64, bool, charString, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, PathBufFromStruse std::str::FromStr;
#[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!
}
Option<T> fields return None when the environment variable is not set.
#[derive(FromEnv)]
struct Config {
host: String, // Required
port: Option<u16>, // Optional, returns None if not set
}
The from_env() method returns Result<Self, FromEnvError>.
use derive_from_env::{FromEnv, FromEnvError};
#[derive(FromEnv)]
struct Config {
host: String,
port: u16,
}
fn main() {
match Config::from_env() {
Ok(config) => println!("Loaded config: {:?}", config),
Err(FromEnvError::MissingEnvVar { var_name }) => {
eprintln!("Missing required variable: {}", var_name);
}
Err(FromEnvError::ParsingFailure { var_name, expected_type }) => {
eprintln!("Failed to parse {} as {}", var_name, expected_type);
}
}
}
MIT