Skip to main content
This guide uses reqwest to send an HTTP GET from Sifr. reqwest is a good async Rust interop example because real HTTP work usually needs a bridge: response shaping, error normalization, and an explicit async contract.

Why this shape

A raw reqwest::Client API is richer than a Sifr declaration should expose. Status codes, body bytes, header maps, and error variants all need a stable Sifr-facing shape. That adaptation belongs in a local bridge under src/bridges. Four rules drive the reqwest path:
  1. Async Rust targets need async def. Sifr rejects hiding a future behind a sync declaration.
  2. Futures are Send by default. Current-thread-only futures need an explicit @rust.async(thread_affinity=tokio_current_thread) contract.
  3. Bridges adapt; declarations stay typed. Convert Rust types into Sifr records or Result channels in the bridge, then bind the bridge function with @rust(...).
  4. No hidden runtimes or blocking. Sifr does not invent a Tokio runtime for you, and it rejects hiding block_on inside an async path.
Direct @rust(reqwest....) bindings are only for Rust items whose signatures already match Sifr. Prefer a bridge for HTTP.

Package setup

Cargo.toml
sifr.toml
Run sifr bridge check before you rely on the declaration in ordinary builds.

Write the bridge

src/bridges/http.rs
The bridge owns reqwest details. The Sifr side only sees str in and Result[str, ...] out.

Declare and call

bridge.http.fetch_text resolves to your package-local module under src/bridges. The nominal RustPanicError member reserves that error surface, but current async code generation does not catch panics while polling the returned Rust future. Do not rely on async panic containment here. panic=map_error(path) is synchronous-only and is rejected on async def until generated async panic wrappers receive runtime certification. If you need status and body together, return a Sifr record from the bridge instead of a bare string:

What not to do

  • Do not call blocking reqwest APIs from async Sifr without an explicit blocking offload annotation and workflow.
  • Do not store borrowed response views across await points.
  • Do not expect Sifr to start Tokio for you outside the package’s normal async runtime setup.

Next steps