Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment Variables

The EnvVars structure allows the insertion of environment variables into a custom container where the name of the fields match the name of the variables. .env files are also supported but they should be restricted to development environments.

The unsafe std::env::set_var function is not invoked due to concerns about concurrent access, therefore, direct usage of std::env::var is not recommended unless:

  1. EnvVars is not used at all.
  2. There are no .env files.
  3. A specific variable is always originated from the current process.

Example

//! `EnvVars` allows the interactive reading of environment variables.

extern crate wtx;

use std::sync::OnceLock;
use wtx::{
  calendar::{DateTime, Utc},
  collections::{ArrayVectorCopy, Vector},
  misc::{EnvVars, Secret, SecretContext},
  rng::{ChaCha20, CryptoSeedableRng},
};

static VARS: OnceLock<Vars> = OnceLock::new();

fn main() -> wtx::Result<()> {
  let http_secret = "Top secret information retrieved from a remote password vault";
  let others = [("HTTP_SECRET".into(), http_secret.into())];
  let _rslt = VARS.set(EnvVars::from_available(others)?.finish());
  let Vars { http_secret, now, port, root_ca, rust_log } = VARS.wait();
  println!("`NOW={now:?}`, `PORT={port}`, `ROOT_CA={root_ca:?}` and `RUST_LOG={rust_log:?}`");
  let buffer = ArrayVectorCopy::<_, 128>::new();
  http_secret.peek(&mut buffer.into(), |_unencrypted_secret| {
    // Make API requests, decrypt AES, sign documents, do a flip, etc...
  })?;
  Ok(())
}

#[derive(Debug, wtx::FromVars)]
struct Vars {
  #[from_vars(map_secret)]
  http_secret: Secret,
  #[from_vars(map_now)]
  now: Option<DateTime<Utc>>,
  port: u16,
  root_ca: Vector<u8>,
  rust_log: Option<String>,
}

fn map_now(var: String) -> wtx::Result<DateTime<Utc>> {
  DateTime::from_iso8601(var.as_bytes())
}

fn map_secret(var: String) -> wtx::Result<Secret> {
  let mut rng = ChaCha20::from_getrandom()?;
  let secret_context = SecretContext::new(&mut rng)?;
  Secret::new(&mut var.into_bytes(), &mut rng, secret_context)
}