CLI entrypoints with clap + Effect
Rust’s standard answer for parsing is clap. For id_effect, treat the binary as a thin shell:
- Parse argv into a struct (
#[derive(clap::Parser)]). - Assemble layers /
MapConfigProvider/ otherRvalues from flags and environment. - Run your program
Effect<A, E, R>withrun_blocking(or an async driver when you integrate Tokio). - Exit with [
std::process::ExitCode] usingid_effect_clihelpers (see the next sections).
This mirrors Effect.ts @effect/cli: declarative argument models composed into a single program — here the “program” is an Effect value rather than a Future chain.
Recommended main shape (Rust 1.61+)
Returning ExitCode keeps main testable and avoids calling std::process::exit deep inside library code:
use clap::Parser; use id_effect_cli::{run_main, RunMainConfig}; #[derive(Parser)] struct Cli { #[arg(long)] name: String, } fn main() -> std::process::ExitCode { let cli = Cli::parse(); let eff = my_app(cli.name); run_main(eff, my_env(), RunMainConfig::with_tracing()) }
my_app returns an Effect<…>; my_env() is whatever R your effect needs (often a Context built from Layer stacks).
Workspace helpers
The id_effect_cli crate (same repository) provides:
- Optional
clapdependency (feature flag; on by default for convenience). run_main— optional tracing install,run_blocking, stderr logging forErr,ExitCodemapping.exit_code_for_exit/exit_code_for_causewhen you already have anExitfromrun_testor a supervisor.
Template
See the checked-in example examples/cli-minimal (--token …, Secret via id_effect_config).
Further reading
- Exit codes for
main—Exit/Cause→ExitCodetable - Config +
Secretfrom flags — wiringid_effect_configat the edge - Error handling —
Causevs plainE - Configuration (
id_effect_config)