valorant_api 0.0.4

A library for interacting with the ingame Valorant-API.
Documentation
use crate::errors::response_error::RequestError;
use crate::utils::credentials_manager::CredentialsManager;
use crate::utils::network::http_client::HttpClient;
use hyper::body::Bytes;
use hyper::{Body, Request};
use serde::de::DeserializeOwned;
use std::collections::HashMap;
use url::Url;

pub(crate) async fn fetch_endpoint<T: HttpClient, D: DeserializeOwned>(
    credentials_manager: &CredentialsManager,
    http_client: &T,
    uri: &Url,
    method: &str,
    body: &str,
    headers: &HashMap<String, String>,
) -> Result<D, RequestError> {
    let raw_result =
        fetch_endpoint_raw(credentials_manager, http_client, uri, method, body, headers).await?;
    serde_json::from_slice(&raw_result).map_err(|e| e.into())
}

async fn fetch_endpoint_raw<T: HttpClient>(
    credentials_manager: &CredentialsManager,
    http_client: &T,
    uri: &Url,
    method: &str,
    body: &str,
    headers: &HashMap<String, String>,
) -> Result<Bytes, RequestError> {
    let auth_headers = credentials_manager.get_auth_headers().await?;
    let headers = headers
        .iter()
        .chain(auth_headers.iter())
        .map(|(key, value)| (key.clone(), value.clone()))
        .collect::<HashMap<String, String>>();

    let request = build_request(uri, method, body, &headers)?;

    let response = http_client.request(request).await?;
    let status = response.status();
    let body = hyper::body::to_bytes(response.into_body()).await?;

    if !status.is_success() {
        return Err(RequestError::from((status.as_u16(), body)));
    }

    Ok(body)
}

fn build_request(
    uri: &Url,
    method: &str,
    body: &str,
    headers: &HashMap<String, String>,
) -> Result<Request<Body>, RequestError> {
    let mut request = hyper::Request::builder()
        .method(method)
        .uri(uri.as_str())
        .body(hyper::Body::from(body.to_string()))
        .map_err(|e| RequestError::ParseError(e.to_string()))?;
    headers.iter().for_each(|(key, value)| {
        let header_key = hyper::header::HeaderName::from_bytes(key.as_bytes());
        let header_key = match header_key {
            Ok(header_key) => header_key,
            Err(_) => return,
        };
        let header_value = hyper::header::HeaderValue::from_str(value);
        let header_value = match header_value {
            Ok(header_value) => header_value,
            Err(_) => return,
        };
        request.headers_mut().append(header_key, header_value);
    });

    Ok(request)
}