hitomi_la 0.1.0

A hitomi.la API wrapper for Rust
Documentation
use std::time::Duration;

use reqwest::{
    Method, Response, StatusCode,
    header::{self, HeaderMap, HeaderName, HeaderValue},
};

pub const BASE_DOMAIN: &str = "gold-usergeneratedcontent.net";

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Reqwest: {0}")]
    Reqwest(#[from] reqwest::Error),

    #[error("Status: {0}")]
    Status(StatusCode),
}

pub async fn request(method: Method, url: &str) -> Result<Response, Error> {
    request_with_headers(method, std::iter::empty(), url).await
}

pub async fn request_with_headers(
    method: Method,
    headers: impl Iterator<Item = (HeaderName, HeaderValue)>,
    url: &str,
) -> Result<Response, Error> {
    let client = reqwest::Client::builder().zstd(true).build().unwrap();

    let mut request = client
        .request(method, url)
        .header(header::REFERER, "https://hitomi.la")
        .headers(HeaderMap::from_iter(headers));

    let is_ltn = url.starts_with("https://ltn.");

    if is_ltn {
        request = request.timeout(Duration::from_secs(3));
    }

    let mut retry = 0;

    let resp = loop {
        let resp = request.try_clone().unwrap().send().await;

        let resp = match resp {
            Ok(resp) => resp,
            Err(err) => {
                if is_ltn && err.is_timeout() && retry < 10 {
                    retry += 1;
                    continue;
                } else {
                    return Err(err.into());
                }
            }
        };

        break resp;
    };

    Ok(resp)
}