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, ProcessRuntime describe what you need; provider impls install live or test doubles.
  • Test doublesTestFileSystem is in-memory; production uses LiveFileSystemProvider.
  • Stable HTTP boundary — domain code depends on the HttpClient trait + execute, not reqwest::RequestBuilder (the capability service is crate-private).

Modules

ModuleResponsibility
errorHttpError, FsError, ProcessError, PlatformError
httpHttpRequest / HttpResponse, HttpClient, ReqwestHttpClientProvider, execute (key is internal)
fsFileSystem, LiveFileSystemProvider, TestFileSystem, read
processCommandSpec, ProcessRuntime, spawn_wait
uriURI 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.