apple 0.2.0

A Rust library for Apple Sign-In authentication, CloudKit Web Services, and App Store Server API
Documentation
use serde::{Deserialize, Serialize};
use std::fmt;
use url::Url;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub enum ResponseMode {
    Query,
    Fragment,
    #[default]
    FormPost,
}

impl fmt::Display for ResponseMode {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ResponseMode::Query => write!(f, "query"),
            ResponseMode::Fragment => write!(f, "fragment"),
            ResponseMode::FormPost => write!(f, "form_post"),
        }
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub enum ResponseType {
    Code,
    #[default]
    CodeId,
}

impl fmt::Display for ResponseType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ResponseType::Code => write!(f, "code"),
            ResponseType::CodeId => write!(f, "code id_token"),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthorizeURLConfig {
    pub client_id: String,
    pub redirect_uri: String,
    pub state: Option<String>,
    pub scope: Option<Vec<String>>,
    pub nonce: Option<String>,
    pub response_mode: Option<ResponseMode>,
    pub response_type: Option<ResponseType>,
}

pub fn authorize_url(cfg: AuthorizeURLConfig) -> String {
    let mut url = Url::parse("https://appleid.apple.com/auth/authorize").unwrap();
    let mut query = url.query_pairs_mut();

    query.append_pair(
        "response_type",
        &cfg.response_type.unwrap_or_default().to_string(),
    );
    query.append_pair(
        "response_mode",
        &cfg.response_mode.unwrap_or_default().to_string(),
    );
    query.append_pair("client_id", &cfg.client_id);
    query.append_pair("redirect_uri", &cfg.redirect_uri);

    if let Some(state) = cfg.state {
        query.append_pair("state", &state);
    }
    if let Some(nonce) = cfg.nonce {
        query.append_pair("nonce", &nonce);
    }
    if let Some(scope) = cfg.scope {
        query.append_pair("scope", &scope.join(" "));
    }

    drop(query);
    url.to_string()
}