valorant_api 0.0.4

A library for interacting with the ingame Valorant-API.
Documentation
#[cfg(feature = "puuid")]
use base64::alphabet::URL_SAFE;
#[cfg(feature = "puuid")]
use base64::engine::{GeneralPurpose, GeneralPurposeConfig};
#[cfg(feature = "puuid")]
use base64::Engine;
#[cfg(feature = "puuid")]
use serde::de::DeserializeOwned;
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serializer};
use std::fmt::Display;
use time::OffsetDateTime;
use url::Url;

pub(crate) fn set_query_args<K: Display, V: Display>(
    url: &mut Url,
    query_args: impl Iterator<Item = (K, V)>,
) {
    //! Set the query arguments of a url
    //! # Arguments
    //! * `url` - The url
    //! * `query_args` - The query arguments
    //! # Example
    //! ```rust no_run
    //! let mut url = Url::parse("https://example.com").expect("Error while parsing url");
    //! let mut queries = HashMap::new();
    //! queries.insert(QueryArg::StartIndex, "0".to_string());
    //! queries.insert(QueryArg::EndIndex, "20".to_string());
    //! valorant_api::set_query_args(&mut url, queries);
    //! ```

    let mut args = url.query_pairs_mut();
    query_args.into_iter().for_each(|(key, value)| {
        args.append_pair(format!("{}", key).as_str(), format!("{}", value).as_str());
    });
}

pub(crate) fn de_milliseconds<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
where
    D: Deserializer<'de>,
{
    let millis: i64 = Deserialize::deserialize(deserializer)?;
    OffsetDateTime::from_unix_timestamp(millis / 1000).map_err(Error::custom)
}

pub(crate) fn se_milliseconds<S>(x: &OffsetDateTime, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    s.serialize_i64(x.unix_timestamp())
}

#[cfg(feature = "puuid")]
#[derive(Debug)]
pub enum DecodeJWTError {
    Decode(base64::DecodeError),
    InvalidBase64,
    Parse(serde_json::Error),
}

#[cfg(feature = "puuid")]
impl Display for DecodeJWTError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DecodeJWTError::Decode(e) => write!(f, "Decode error: {}", e),
            DecodeJWTError::InvalidBase64 => write!(f, "Invalid base64"),
            DecodeJWTError::Parse(e) => write!(f, "Parse error: {}", e),
        }
    }
}

#[cfg(feature = "puuid")]
pub(crate) fn decode_jwt<T: DeserializeOwned>(result: &str) -> Result<T, DecodeJWTError> {
    let parts: Vec<&str> = result.split('.').collect();
    let base64 = parts.get(1).ok_or(DecodeJWTError::InvalidBase64)?;
    let base64 = base64.replace('-', "+").replace('_', "/");
    let decoded = GeneralPurpose::new(&URL_SAFE, GeneralPurposeConfig::new())
        .decode(base64.as_bytes())
        .map_err(DecodeJWTError::Decode)?;
    serde_json::from_slice(&decoded).map_err(DecodeJWTError::Parse)
}