# envkit `envkit` is a small Rust crate for reading environment variables as typed values. It provides a minimal loader API for required values, optional values, defaults, prefixed variable names, and simple `.env`-style files. ## Install Add `envkit` to your `Cargo.toml`: ```toml [dependencies] envkit = "0.2.1" ``` ## Quick Start ```rust use envkit::EnvLoader; fn main() -> Result<(), envkit::error::EnvError> { let env = EnvLoader::new(); let port: u16 = env.get("PORT")?; let debug: bool = env.get_or("DEBUG", false); let app_name: String = env .get_opt("APP_NAME") .unwrap_or_else(|| "envkit".to_string()); println!("{app_name} listening on port {port}; debug={debug}"); Ok(()) } ``` ## API ### `EnvLoader::get` Reads a required environment variable and parses it into the requested type. ```rust let env = envkit::EnvLoader::new(); let port: u16 = env.get("PORT")?; ``` Returns `EnvError::MissingVar` when the variable is not set and `EnvError::Invalid` when parsing fails. ### `EnvLoader::get_or` Reads an environment variable and returns a fallback when the variable is missing or invalid. ```rust let debug: bool = env.get_or("DEBUG", false); ``` ### `EnvLoader::get_opt` Reads an environment variable and returns `None` when the variable is missing or invalid. ```rust let name: Option = env.get_opt("APP_NAME"); ``` ### `EnvLoader::with_prefix` Creates a loader that prepends a prefix to every key. ```rust let app = env.with_prefix("APP_"); let host: String = app.get("HOST")?; // reads APP_HOST let port: u16 = app.get_or("PORT", 8080); // reads APP_PORT ``` ### `EnvLoader::load_file` Loads variables from a file with one `KEY=VALUE` pair per line. ```rust let env = envkit::EnvLoader::new(); env.load_file(".env")?; ``` Blank lines and lines starting with `#` are ignored. Keys and values are trimmed before being written into the process environment. Example file: ```text # .env PORT=8080 DEBUG=true APP_NAME=envkit ``` ## Supported Types Built-in parsing supports: - `String` - `bool` - signed integers: `i8`, `i16`, `i32`, `i64`, `i128`, `isize` - unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128`, `usize` - floats: `f32`, `f64` - `Vec` where `T` also implements `FromEnv` Boolean values accept: - `true` / `false` - `1` / `0` - `t` / `f` - `yes` / `no` Lists are comma-separated and each item is trimmed before parsing: ```rust let env = envkit::EnvLoader::new(); let ports: Vec = env.get("PORTS")?; let flags: Vec = env.get("FEATURE_FLAGS")?; ``` ## Custom Types Implement `FromEnv` for your own types when you want domain-specific parsing. ```rust use envkit::{error::EnvError, FromEnv}; enum LogFormat { Json, Pretty, } impl FromEnv for LogFormat { fn from_env(value: &str) -> Result { match value.trim().to_lowercase().as_str() { "json" => Ok(Self::Json), "pretty" => Ok(Self::Pretty), other => Err(EnvError::invalid( "LogFormat", other, "expected `json` or `pretty`", )), } } } ``` ## Errors `envkit` returns `EnvError` values: - `EnvError::MissingVar(key)` when a required environment variable is not set. - `EnvError::Invalid { key, value, message }` when a value cannot be parsed. - `EnvError::FileError { path, message }` when a file cannot be read or contains an invalid line. ## Examples Run the included examples with: ```bash cargo run --example basic cargo run --example prefixed ``` The examples seed their own environment variables so they can be run directly. ## Development Run the test suite with: ```bash cargo test ```