use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Post {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<u32>,
user_id: u32,
title: String,
body: String,
}
#[derive(Debug, Deserialize)]
struct Empty {}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = wrest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let base = "https://jsonplaceholder.typicode.com/posts";
println!("=== 1. POST (create) ===\n");
let new_post = Post {
id: None,
user_id: 42,
title: "Hello from wrest".into(),
body: "This post was created by the wrest json_crud example.".into(),
};
let created: Post = client
.post(base)
.json(&new_post)
.send()
.await?
.error_for_status()?
.json()
.await?;
println!("Created: {created:#?}");
println!(" -> Server assigned id = {:?}\n", created.id);
println!("=== 2. GET (read) ===\n");
let fetched: Post = client
.get(format!("{base}/1"))
.send()
.await?
.error_for_status()?
.json()
.await?;
println!("Fetched: {fetched:#?}\n");
println!("=== 3. PUT (full update) ===\n");
let updated_post = Post {
id: Some(1),
user_id: 1,
title: "Updated title via PUT".into(),
body: "Completely replaced body.".into(),
};
let resp = client
.put(format!("{base}/1"))
.header("X-Custom-Header", "wrest-example")
.json(&updated_post)
.send()
.await?
.error_for_status()?;
println!("PUT status: {}", resp.status());
let updated: Post = resp.json().await?;
println!("Updated: {updated:#?}\n");
println!("=== 4. PATCH (partial update) ===\n");
#[derive(Serialize)]
struct PatchBody {
title: String,
}
let patch = PatchBody {
title: "Patched title only".into(),
};
let resp = client
.patch(format!("{base}/1"))
.json(&patch)
.send()
.await?
.error_for_status()?;
println!("PATCH status: {}", resp.status());
let patched: Post = resp.json().await?;
println!("Patched: {patched:#?}\n");
println!("=== 5. DELETE ===\n");
let resp = client
.delete(format!("{base}/1"))
.send()
.await?
.error_for_status()?;
println!("DELETE status: {} (expect 200)", resp.status());
let _empty: Empty = resp.json().await?;
println!("Response body: {{}}\n");
println!("Done -- all CRUD operations succeeded!");
Ok(())
}