use std::marker::PhantomData;
use super::scopes::{HasAddress, HasEmail, HasPhone, HasProfile, ScopeSet};
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
pub struct AddressClaim {
#[serde(skip_serializing_if = "Option::is_none")]
pub formatted: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub street_address: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub locality: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub postal_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub country: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Claims<S: ScopeSet> {
pub iss: String,
pub sub: String,
pub aud: Vec<String>,
pub exp: i64,
pub iat: i64,
pub nonce: String,
pub azp: Option<String>,
pub auth_time: Option<i64>,
pub acr: Option<String>,
pub amr: Option<Vec<String>>,
pub(crate) email: Option<String>,
pub(crate) email_verified: Option<bool>,
pub(crate) name: Option<String>,
pub(crate) given_name: Option<String>,
pub(crate) family_name: Option<String>,
pub(crate) middle_name: Option<String>,
pub(crate) nickname: Option<String>,
pub(crate) preferred_username: Option<String>,
pub(crate) profile: Option<String>,
pub(crate) picture: Option<String>,
pub(crate) website: Option<String>,
pub(crate) gender: Option<String>,
pub(crate) birthdate: Option<String>,
pub(crate) zoneinfo: Option<String>,
pub(crate) locale: Option<String>,
pub(crate) updated_at: Option<i64>,
pub(crate) phone_number: Option<String>,
pub(crate) phone_number_verified: Option<bool>,
pub(crate) address: Option<AddressClaim>,
pub(crate) _scope: PhantomData<S>,
}
impl<S: HasEmail> Claims<S> {
#[must_use]
pub fn email(&self) -> &str {
self.email
.as_deref()
.expect("HasEmail bound implies email Some — IdP drift if absent")
}
#[must_use]
pub fn email_verified(&self) -> Option<bool> {
self.email_verified
}
}
impl<S: HasProfile> Claims<S> {
#[must_use]
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
#[must_use]
pub fn given_name(&self) -> Option<&str> {
self.given_name.as_deref()
}
#[must_use]
pub fn family_name(&self) -> Option<&str> {
self.family_name.as_deref()
}
#[must_use]
pub fn middle_name(&self) -> Option<&str> {
self.middle_name.as_deref()
}
#[must_use]
pub fn nickname(&self) -> Option<&str> {
self.nickname.as_deref()
}
#[must_use]
pub fn preferred_username(&self) -> Option<&str> {
self.preferred_username.as_deref()
}
#[must_use]
pub fn profile(&self) -> Option<&str> {
self.profile.as_deref()
}
#[must_use]
pub fn picture(&self) -> Option<&str> {
self.picture.as_deref()
}
#[must_use]
pub fn website(&self) -> Option<&str> {
self.website.as_deref()
}
#[must_use]
pub fn gender(&self) -> Option<&str> {
self.gender.as_deref()
}
#[must_use]
pub fn birthdate(&self) -> Option<&str> {
self.birthdate.as_deref()
}
#[must_use]
pub fn zoneinfo(&self) -> Option<&str> {
self.zoneinfo.as_deref()
}
#[must_use]
pub fn locale(&self) -> Option<&str> {
self.locale.as_deref()
}
#[must_use]
pub fn updated_at(&self) -> Option<i64> {
self.updated_at
}
}
impl<S: HasPhone> Claims<S> {
#[must_use]
pub fn phone_number(&self) -> Option<&str> {
self.phone_number.as_deref()
}
#[must_use]
pub fn phone_number_verified(&self) -> Option<bool> {
self.phone_number_verified
}
}
impl<S: HasAddress> Claims<S> {
#[must_use]
pub fn address(&self) -> Option<&AddressClaim> {
self.address.as_ref()
}
}