Env — The Runtime Capability Container

Multi-capability effects use Env at runtime: a map from capability identity to service value. Insertion order does not matter.

Structure

#![allow(unused)]
fn main() {
use id_effect::Env;

let mut env = Env::new();
env.insert::<Cap<Database>>(pool);
env.insert::<Cap<EffectLogger>>(logger);

assert!(env.has::<Cap<Database>>());
let pool = env.get::<Cap<Database>>();
}

Env stores cloneable, Send + Sync values keyed by CapabilityId (derived from the key type). Lookups are O(1); there is no positional indexing.

Building Env

Three common paths:

1. Application entry — providers + graph

#![allow(unused)]
fn main() {
run_with([provide!(ConfigLive), provide!(DatabaseLive)], app())?;
}

2. Providers only — reuse in tests

#![allow(unused)]
fn main() {
let env = build_env([provide!(MockDatabaseLive)])?;
}

3. Manual — fast unit tests

#![allow(unused)]
fn main() {
let mut env = Env::new();
env.insert::<Cap<Database>>(MockPool::new());
}

Why not a plain HashMap<TypeId, Box<dyn Any>>?

You could store dyn Any and downcast. Env + Capability keeps:

  • Compile-time requirements via Needs<K> bounds and caps!
  • Typed accessget::<Cap<Database>>() returns &Pool, not &dyn Any
  • Stable diagnostics — missing capabilities produce CapabilityError::Missing with the key name

Application code should think in Env and capability services, not positional tuples.

Order independence

These two sequences produce equivalent lookup behaviour:

#![allow(unused)]
fn main() {
env.insert::<Cap<Database>>(db).insert::<Cap<EffectLogger>>(log);
// vs
env.insert::<Cap<EffectLogger>>(log).insert::<Cap<Database>>(db);
}

Adding a new capability never changes how existing keys are accessed — refactor-safe in a way tuples never were.

When you touch Env directly

  • Test fixtures with one or two mocks
  • Tokio/async examples that pass Env to run_async
  • HTTP hosts that store State<Env> (see Axum host)

Production apps usually list provide!(…) values once at the top level and let CapabilityGraph assemble Env.