Rust

Асинхронный HTTP-клиент на tokio и reqwest

Algonexys · 07.08.2026 · 👁 0

Параллельные запросы, таймауты и разбор JSON в типизированную структуру.

Код

// Cargo.toml:
// tokio = { version = "1", features = ["full"] }
// reqwest = { version = "0.12", features = ["json"] }
// serde = { version = "1", features = ["derive"] }
// futures = "0.3"

use std::time::Duration;

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Repo {
    name: String,
    stargazers_count: u32,
    #[serde(default)]
    description: Option<String>,
}

async fn fetch_repo(client: &reqwest::Client, full_name: &str) -> anyhow::Result<Repo> {
    let repo = client
        .get(format!("https://api.github.com/repos/{full_name}"))
        .timeout(Duration::from_secs(15))
        .send()
        .await?
        .error_for_status()?
        .json::<Repo>()
        .await?;
    Ok(repo)
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let client = reqwest::Client::builder()
        .user_agent("DigitMind/1.0")
        .build()?;

    let names = ["rust-lang/rust", "django/django", "tokio-rs/tokio"];

    // Все запросы параллельно
    let results = futures::future::join_all(
        names.iter().map(|name| fetch_repo(&client, name))
    ).await;

    for result in results {
        match result {
            Ok(repo) => println!("{}: {} ★", repo.name, repo.stargazers_count),
            Err(e) => eprintln!("Ошибка: {e}"),
        }
    }
    Ok(())
}