Load .env in Rust
Hello Rustaceans!
Are you tired of handling multiple environment variables in a messy way? Let me
show you how to load .env
files into typesafe structs in Rust, making your
code cleaner and more maintainable.
Initially, I used the
for loading dotenvy crate.env
files like this:
use std::env;
fn main() {
dotenvy::dotenv().ok();
let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file");
println!("DATABASE_URL {:?}", db_url);
}
This method is straightforward but quickly becomes unmanageable with more environment variables.
As a former TypeScript user, I appreciated how the zod
library ensured that
all required environment variables were present:
const envSchema = z.object({
JOB_ID: z.string().min(1),
CLOUDFLARE_R2_ACCOUNT_ID: z.string().min(1),
CLOUDFLARE_R2_ACCESS_KEY_ID: z.string().min(1),
CLOUDFLARE_R2_SECRET_ACCESS_KEY: z.string().min(1)
});
const env = envSchema.parse(process.env);
This approach kept things organized and error-free. So, I wondered, can we achieve something similar in Rust?
My search led me to the , which does exactly what I needed in Rust: envy crate
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Config {
database_url: String,
}
fn main() {
dotenvy::dotenv().ok();
let config = envy::from_env::<Config>().unwrap();
println!("DATABASE_URL {:?}", config.database_url);
}
With envy
, you can easily map environment variables to a typesafe struct.
envy
goes beyond basic deserialization. It supports Option
types,
Vecs
, and more. You can even set default values using serde’s attributes:
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Config {
database_url: String,
#[serde(default = "default_min_block_confirmations")]
min_block_confirmations: u8,
}
fn default_min_block_confirmations() -> u8 {
100
}
fn main() {
dotenvy::dotenv().ok();
let config = envy::from_env::<Config>().unwrap();
println!("DATABASE_URL {:?}", config.database_url);
println!("MIN_BLOCK_CONFIRMATIONS {:?}", config.min_block_confirmations);
}
For those who prefer prefixed environment variables, envy
has got you covered:
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Config {
database_url: String,
#[serde(default = "default_min_block_confirmations")]
min_block_confirmations: u8,
}
fn main() {
dotenvy::dotenv().ok();
let config = envy::prefixed("APP_").from_env::<Config>().unwrap();
println!("APP_DATABASE_URL {:?}", config.database_url);
println!("APP_MIN_BLOCK_CONFIRMATIONS {:?}", config.min_block_confirmations);
}
There you have it! Loading .env
files into typesafe structs in Rust is
simple and efficient with envy
. This approach keeps your code neat and your
variables organized. Give it a try, and you’ll see how it can streamline your
Rust projects.
Happy coding, and keep Rust-ing!
TAGS
*post-tags*
- [1]
LINKS
*post-links*
- [1]
- [2]
- [3]