I would like to load a set of Rust environment variables depending on my build environment (in my case, dev, uat and live). Ideally, I would like to specify the environment file ay build time.
Looking at online docs, the advice seems to be to use the dotenv
crate. However, that crate is a v0 version, and does not appear to be maintained. Is there an idiomatic way to do this without using an old library?
Without external libraries you can use cargo
configuration env
property and have something like:
Options A: Single configuration
my-project/.cargo/config.toml
[env]
MY_ENV="dev"
MY_DEV_HOST="localhost"
MY_PROD_HOST="prod.example.com"
my-project/src/main.rs
fn main() -> Result<(), Box<dyn Error>> {
let my_env = env::var("MY_ENV")
.unwrap_or("dev".to_string())
.to_uppercase();
let my_host = env::var(format!("MY_{}_HOST", my_env))?;
// Do something
Ok(())
}
then you run it with cargo run
and it will take the default dev
values, with MY_ENV="prod" cargo run
will take prod values.
Option B: Multiple configuration
Another options if is a configuration per environment and use --config
cargo command line option, for example:
my-project/stg-config.toml
[env]
MY_ENV="stg"
MY_HOST="stg.example.com"
my-project/prod-config.toml
[env]
MY_ENV="prod"
MY_HOST="prod.example.com"
and then cargo run --config stg-config.toml
, if you have .cargo/config.toml
(with default env
values) it will merge those.