valorant_api 0.3.14

A library for interacting with the ingame Valorant-API.
Documentation
use std::collections::HashMap;

use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use serde::{Deserialize, Serialize};

use crate::enums::platform::Platform;
use crate::errors::response_error::RequestError;
use crate::response_types::version::{ValorantAPIData, Version};

const ENTITLEMENTS_HEADER_KEY: &str = "X-Riot-Entitlements-JWT";
const CLIENT_VERSION_HEADER_KEY: &str = "X-Riot-ClientVersion";
const CLIENT_PLATFORM_HEADER_KEY: &str = "X-Riot-ClientPlatform";
const AUTHORIZATION_HEADER_KEY: &str = "Authorization";

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialsManager {
    pub platform: Platform,
    pub access_token: String,
    pub entitlements_token: String,
    pub client_version: String,
}

impl CredentialsManager {
    pub async fn new_with_tokens(
        platform: Platform,
        access_token: String,
        entitlements_token: String,
    ) -> reqwest::Result<CredentialsManager> {
        Ok(CredentialsManager {
            platform,
            access_token,
            entitlements_token,
            client_version: Self::get_client_version().await?,
        })
    }

    pub fn with_platform(&mut self, platform: Platform) -> &mut CredentialsManager {
        self.platform = platform;
        self
    }

    pub(super) async fn get_auth_headers(&self) -> Result<HashMap<String, String>, &str> {
        let mut headers: HashMap<String, String> = HashMap::new();
        headers.insert(
            AUTHORIZATION_HEADER_KEY.to_string(),
            format!("Bearer {}", self.access_token),
        );
        headers.insert(
            ENTITLEMENTS_HEADER_KEY.to_string(),
            self.entitlements_token.to_string(),
        );
        headers.insert(
            CLIENT_VERSION_HEADER_KEY.to_string(),
            self.client_version.to_string(),
        );
        headers.insert(
            CLIENT_PLATFORM_HEADER_KEY.to_string(),
            self.get_client_platform()
                .map_err(|_| "Failed to get client platform")?,
        );

        Ok(headers)
    }

    async fn get_client_version() -> reqwest::Result<String> {
        reqwest::get("https://valorant-api.com/v1/version")
            .await?
            .json::<ValorantAPIData<Version>>()
            .await
            .map(|r: ValorantAPIData<Version>| r.data.riot_client_version)
    }

    fn get_client_platform(&self) -> Result<String, RequestError> {
        let client_platform = self.platform.get_client_version();
        serde_json::to_string(&client_platform)
            .map(|s| BASE64_STANDARD.encode(s.as_bytes()))
            .map_err(|_| {
                RequestError::ParseError("Failed to serialize client platform".to_string())
            })
    }
}

unsafe impl Send for CredentialsManager {}
unsafe impl Sync for CredentialsManager {}