Platform I/O (id_effect_platform)
Workspace crate id_effect_platform mirrors Effect.ts @effect/platform: HTTP, filesystem, and process as typed capabilities in Env, not ad hoc reqwest / std::fs calls in domain code.
Why separate from id_effect?
- Ports, not drivers — traits like
HttpClient,FileSystem,ProcessRuntimedescribe what you need; provider impls install live or test doubles. - Test doubles —
TestFileSystemis in-memory; production usesLiveFileSystemProvider. - Stable HTTP boundary — domain code depends on the
HttpClienttrait +execute, notreqwest::RequestBuilder(the capability service is crate-private).
Modules
| Module | Responsibility |
|---|---|
error | HttpError, FsError, ProcessError, PlatformError |
http | HttpRequest / HttpResponse, HttpClient, ReqwestHttpClientProvider, execute (key is internal) |
fs | FileSystem, LiveFileSystemProvider, TestFileSystem, read |
process | CommandSpec, ProcessRuntime, spawn_wait |
uri | URI helpers |
Wiring pattern
Each module declares a capability service and ships a default provider:
#![allow(unused)] fn main() { // in id_effect_platform::http (simplified; HttpClientService is pub(crate)) #[derive(ProviderSpecDerive)] #[provides(HttpClientService)] pub struct ReqwestHttpClientProvider; impl ReqwestHttpClientProvider { fn new() -> Arc<dyn HttpClient> { Arc::new(ReqwestHttpClient::default_client()) } } }
Application entry:
#![allow(unused)] fn main() { use id_effect::{run_with, RunError}; use id_effect_platform::http::{HttpRequest, execute, provide_reqwest_http_client}; let res = run_with( [provide_reqwest_http_client()], execute(HttpRequest::get("https://example.com")), ) .map_err(|e| match e { RunError::Effect(e) => e, e => panic!("planner: {e}"), })?; }
Effects returned by execute carry the correct Needs bound internally; application code usually calls run_with([provide_reqwest_http_client()], execute(req)) without naming the key.
Drive async platform effects with id_effect::run_async (see Tokio bridge).
Security note (filesystem)
TestFileSystem rejects paths containing ... Live I/O follows OS semantics — sandbox untrusted paths at a higher layer.
Runnable example
cargo run -p id_effect_platform --example 010_platform_http_get
Next
For reqwest-specific pools and JSON helpers, see HTTP via reqwest.