Provide Default Values
How to handle variables that might not be set by providing a fallback.
What happens if a variable isn’t set? If you use .unwrap()
, your program will
panic with a VariableNotFound
error. To avoid this, you can provide a default
value right in your template string.
The syntax for this is ${VAR:-default}
. If VAR
is missing from the
environment or your HashMap
, envfmt
will use default
instead.
Using Defaults with Environment Variables
Let’s say your app needs an RPC_URL
, but you want it to default to a local
node if the variable isn’t set.
You can write your template like this:
fn main() {
let template = "Using RPC URL: ${RPC_URL:-http://localhost:8545}";
let rpc_url = envfmt::format(template).unwrap();
println!("{}", rpc_url);
}
Now, if you run this without setting the RPC_URL
variable:
cargo run
The output will be:
Using RPC URL: http://localhost:8545
If you do set it, your value will be used instead:
RPC_URL=https://mainnet.infura.io/v3/my-key cargo run
The output will be:
Using RPC URL: https://mainnet.infura.io/v3/my-key
Using Defaults with a HashMap
This works the exact same way with format_with()
and a HashMap
. If a key is
missing from the map, the default value is used.
use std::collections::HashMap;
fn main() {
let mut context = HashMap::new();
context.insert("CHAIN_ID", "1");
// Note that "RPC_URL" is not in the context
let template = "Connecting to ${RPC_URL:-http://localhost:8545} for chain $CHAIN_ID...";
let connection_string = envfmt::format_with(template, &context).unwrap();
println!("{}", connection_string);
}
Running this will print:
Connecting to http://localhost:8545 for chain 1...
What About Empty Variables?
It’s important to know that a default value is only used if the variable is
not set. If the variable is set to an empty string, envfmt
will use the
empty string. This is the same way shells work.
Here’s an example:
use std::collections::HashMap;
fn main() {
let mut context = HashMap::new();
context.insert("ALCHEMY_API_KEY", ""); // Set to an empty string
let template = "Alchemy key: '${ALCHEMY_API_KEY:-not_provided}'";
let message = envfmt::format_with(template, &context).unwrap();
println!("{}", message);
}
The output will be:
Alchemy key: ''
The default value not_provided
was ignored because the ALCHEMY_API_KEY
key
exists in the HashMap
, even though its value is empty.