zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
// {
//   "iss": "https://accounts.google.com",
//   "azp": "<client_id>",
//   "aud": "<client_id>",
//   "sub": "<114329725508509 .....>",
//   "email": "<email>",
//   "email_verified": "true",
//   "at_hash": "<at_hash>",
//   "name": "<张小五>",
//   "picture": "<picture>",
//   "given_name": "<小五>",
//   "family_name": "<张>",
//   "iat": "1713351150",
//   "exp": "1713354750",
//   "alg": "RS256",
//   "kid": "<6ce11aecf9eb14024a44bbfd1bcf8b3 ......>",
//   "typ": "JWT"
// }
#[rustfmt::skip]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct GoogleJWT {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub iss: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub azp: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub aud: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub sub: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub email: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub email_verified: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub at_hash: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub picture: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub given_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub family_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub iat: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub exp: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub alg: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub kid: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub typ: Option<String>,
}

#[rustfmt::skip]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct GitHubToken {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub access_token: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub expires_in: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub refresh_token: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub refresh_token_expires_in: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub token_type: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub scope: Option<String>,
}

#[rustfmt::skip]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct GitHubUserInfo {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub login: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub node_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub gravatar_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub html_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub followers_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub following_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub gists_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub starred_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub subscriptions_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub organizations_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub repos_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub events_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub received_events_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#type: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub site_admin: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub company: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub blog: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub email: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hireable: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bio: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub twitter_username: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub public_repos: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub public_gists: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub followers: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub following: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created_at: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated_at: Option<String>,
}