Mini Post: Parsing Environment Variables Safely in Rust
   bloom 
        ⋄ posted about 2 years ago  ⋄ last updated about 2 years ago  ⋄
        2 min read 
 Almost every app I write nowadays uses an environment file, and therefore I always have to read things from the environment and parse them into different forms. Doing this safely with defaults in Rust was a bit tricky for me at first, but I’ve landed on a solution I like.
Optional Numbers#
The reason I was looking for code like this was to try and get a port for a database from the environment with a reasonable fallback. Here’s what I landed on:
use std::env;use dotenv::dotenv;
fn main() {    dotenv().ok();    let count = env::var("COUNT")        // convert to Option<String>        .ok()        // convert to Option<u64> via parse        .and_then(|value| value.parse::<u64>().ok())        // Use 5 as a default if either the value was not found or it could        // not be converted.        .unwrap_or(5)
    println!("{}", count * 5);}Default Strings#
Of course, you can always just get a required value like this:
std::env;use dotenv::dotenv;
fn main() {    dotenv().ok();    let test = env::var("TEST")        .unwrap_or(String::from("Test"));
    println!("{}", test);}Required Environment Variables#
And of course, you can make them required by just unwraping them, but that
will crash your program:
std::env;use dotenv::dotenv;
fn main() {    dotenv().ok();    let test = env::var("TEST").unwrap();
    println!("{}", test);}thread 'main' panicked at src\main.rs:6:35:called `Result::unwrap()` on an `Err` value: NotPresentYou can instead print a helpful message:
std::env;use dotenv::dotenv;
fn main() {    dotenv().ok();    let test = env::var("TEST");
    match test {        Ok(test) => {            println!("{}", test)        }        Err(_) => {            eprintln!("Missing required environment variable 'TEST'");            return;        }    }}Missing required environment variable 'TEST'