cURL to Rust Converter
Paste a cURL command and get equivalent Rust built on the reqwest blocking client — the de facto HTTP crate for Rust. The parser reads the method, repeated headers, request body, -u basic auth and cookies, then emits a complete fn main() -> Result<(), Box<dyn std::error::Error>> with a chained builder: .request(...), .header(...), .basic_auth(...), .body(...), .send(). The exact Cargo.toml dependency line is included as a comment. Runs entirely in your browser.
How to use the cURL to Rust Converter
Paste a cURL command into the cURL command box — a browser Copy as cURL string with backslash line continuations works. Press Convert to Rust (it also converts as you type) and the Rust code appears below. Click Example to load a JSON POST with a bearer token, then Copy the snippet into src/main.rs. The output starts with a // Cargo.toml: reqwest = { version = "0.12", features = ["blocking"] } comment so you know exactly what to add, then use reqwest::Method;, then a fn main() returning a boxed-error Result. It builds reqwest::blocking::Client::new(), calls .request(Method::POST, url), chains .header(k, v) per header, adds .basic_auth(user, Some(pass)) for -u, attaches .body(...) when there is a payload, and finishes with .send()? plus a resp.status() / resp.text()? read. The trailing ? operators make the boxed-error return type compile cleanly.
Converting cURL to Rust with reqwest
reqwest is the standard high-level HTTP client in the Rust ecosystem, built on hyper and Tokio. It ships two front ends: an async client (the default) and a blocking client behind the blocking feature flag. This converter targets the blocking client because it produces a short, self-contained fn main() that runs without an async runtime, executor macros, or .await sprinkled through the code — ideal for scripts, CLIs and quick API calls. That is also why the generated header comment enables features = ["blocking"]; forget it and the blocking module simply will not exist.
The builder is fluent: Client::new().request(method, url) returns a RequestBuilder you decorate with .header(), .basic_auth() and .body() before calling .send(). Rust’s error handling shapes the output: nearly every step returns a Result, so the function signature is Result<(), Box<dyn std::error::Error>> and each fallible call ends in ? to propagate errors upward. The method is passed as a reqwest::Method value. Basic auth uses .basic_auth(user, Some(pass)) — the password is an Option — rather than a hand-built header. Any Content-Length header is dropped because reqwest derives it from the body.
If you would prefer the async client, the body of the function maps over almost directly — swap the blocking client for reqwest::Client and add .await after .send() and .text(). For the same request in other ecosystems, see the cURL to Python converter or the multi-language cURL converter.
Common use cases
- CLI tools — drop an API call into a Rust binary without wiring up an async runtime.
- DevTools to Rust — turn a browser “Copy as cURL” into a working
reqwestrequest. - Crate scaffolding — bootstrap a third-party integration, then add typed structs, retries or timeouts.
- Documentation — present an endpoint as idiomatic Rust beside the shell example.
- Learning reqwest — see how the builder chain and the
?error operator fit together. - Porting scripts — move a curl-based job into a compiled, type-checked Rust program.
Frequently asked questions
Blocking or async client?
fn main() with no runtime. To go async, switch to reqwest::Client and add .await after .send() and .text().What do I add to Cargo.toml?
reqwest = { version = "0.12", features = ["blocking"] }. The blocking feature is required.Why does main return a Result?
reqwest calls are fallible. The signature Result<(), Box<dyn std::error::Error>> lets each step use the ? operator to propagate errors instead of unwrapping.How is -u basic auth represented?
.basic_auth(user, Some(pass)) — the password is wrapped in Some(...) because the parameter is an Option.