reqres 1.0.0

A pure Rust async HTTP client library based on Tokio with HTTP/2, connection pooling, proxy, cookie, compression, benchmarks, and comprehensive tests
Documentation
use reqres::Client;
use bytes::Bytes;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== reqres v0.4.0 Bytes Client Demo ===\n");

    let client = Client::new()?;

    // 示例 1: 使用 body_bytes() 发送二进制数据
    println!("Sending binary data using body_bytes()...");
    let binary_data = Bytes::from_static(b"Hello, reqres! This is binary data.");
    
    let request = reqres::Request::post("https://httpbin.org/post")
        .body_bytes(binary_data.clone())
        .header("X-Content-Type", "application/octet-stream")
        .build()?;

    match client.request(request).await {
        Ok(response) => {
            println!("✓ Binary data POST successful!");
            println!("  Status: {}", response.status());
            
            // 使用零拷贝的 bytes() 方法获取响应体
            let body_bytes = response.bytes();
            println!("  Response body length: {} bytes", body_bytes.len());
            
            // 将字节转换为文本显示(前 300 个字符)
            if let Ok(text) = String::from_utf8(body_bytes[0..300.min(body_bytes.len())].to_vec()) {
                println!("  Response preview:\n{}", text);
            }
        }
        Err(e) => {
            eprintln!("✗ Binary data POST failed: {}", e);
        }
    }

    println!("\n{}\n", &"=".repeat(50));

    // 示例 2: 演示零拷贝特性 - Bytes 可以高效地共享和克隆
    println!("Demonstrating zero-copy Bytes sharing...");
    let shared_data = Bytes::from("Shared data between requests");
    println!("  Original data: {:?}", shared_data);
    println!("  Original data length: {} bytes", shared_data.len());

    // 克隆 Bytes 只是指针复制,不复制实际数据
    let request1_data = shared_data.clone();
    let request2_data = shared_data.clone();

    println!("  Cloned data length (same as original): {} bytes", request1_data.len());
    println!("  ✓ Bytes::clone() is efficient - only copies the pointer, not the data");

    let request1 = reqres::Request::post("https://httpbin.org/post")
        .body_bytes(request1_data)
        .build()?;

    match client.request(request1).await {
        Ok(response) => {
            println!("✓ Request 1 with shared Bytes successful!");
            println!("  Status: {}", response.status());
        }
        Err(e) => {
            eprintln!("✗ Request 1 failed: {}", e);
        }
    }

    let request2 = reqres::Request::post("https://httpbin.org/post")
        .body_bytes(request2_data)
        .build()?;

    match client.request(request2).await {
        Ok(response) => {
            println!("✓ Request 2 with same Bytes successful!");
            println!("  Status: {}", response.status());
        }
        Err(e) => {
            eprintln!("✗ Request 2 failed: {}", e);
        }
    }

    println!("\n{}\n", &"=".repeat(50));

    // 示例 3: 比较文本 body 和 Bytes body 的性能差异
    println!("Performance comparison: String vs Bytes...");
    
    // 字符串方式(会复制数据)
    let text_body = "Data sent as String".repeat(100);
    let _start = std::time::Instant::now();
    
    let request_text = reqres::Request::post("https://httpbin.org/post")
        .body(text_body.clone())
        .build()?;
    
    match client.request(request_text).await {
        Ok(response) => {
            println!("✓ String body POST successful!");
            println!("  Status: {}", response.status());
        }
        Err(e) => {
            eprintln!("✗ String body POST failed: {}", e);
        }
    }

    // Bytes 方式(零拷贝)
    let bytes_body = Bytes::from("Data sent as Bytes".repeat(100));
    let request_bytes = reqres::Request::post("https://httpbin.org/post")
        .body_bytes(bytes_body.clone())
        .build()?;

    match client.request(request_bytes).await {
        Ok(response) => {
            println!("✓ Bytes body POST successful!");
            println!("  Status: {}", response.status());
        }
        Err(e) => {
            eprintln!("✗ Bytes body POST failed: {}", e);
        }
    }

    println!("\n=== Demo completed ===");
    Ok(())
}