use serde::{Deserialize, Serialize};
use std::fmt::Error as FormatterError;
use std::fmt::{Debug, Display, Formatter};
use crate::{basic::BasicErrorResponseType, ErrorResponseType};
use crate::{AccessToken, RefreshToken};
pub trait RevocableToken {
fn secret(&self) -> &str;
fn type_hint(&self) -> Option<&str>;
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub enum StandardRevocableToken {
AccessToken(AccessToken),
RefreshToken(RefreshToken),
}
impl RevocableToken for StandardRevocableToken {
fn secret(&self) -> &str {
match self {
Self::AccessToken(token) => token.secret(),
Self::RefreshToken(token) => token.secret(),
}
}
fn type_hint(&self) -> Option<&str> {
match self {
StandardRevocableToken::AccessToken(_) => Some("access_token"),
StandardRevocableToken::RefreshToken(_) => Some("refresh_token"),
}
}
}
impl From<AccessToken> for StandardRevocableToken {
fn from(token: AccessToken) -> Self {
Self::AccessToken(token)
}
}
impl From<&AccessToken> for StandardRevocableToken {
fn from(token: &AccessToken) -> Self {
Self::AccessToken(token.clone())
}
}
impl From<RefreshToken> for StandardRevocableToken {
fn from(token: RefreshToken) -> Self {
Self::RefreshToken(token)
}
}
impl From<&RefreshToken> for StandardRevocableToken {
fn from(token: &RefreshToken) -> Self {
Self::RefreshToken(token.clone())
}
}
#[derive(Clone, PartialEq)]
pub enum RevocationErrorResponseType {
UnsupportedTokenType,
Basic(BasicErrorResponseType),
}
impl RevocationErrorResponseType {
fn from_str(s: &str) -> Self {
match BasicErrorResponseType::from_str(s) {
BasicErrorResponseType::Extension(ext) => match ext.as_str() {
"unsupported_token_type" => RevocationErrorResponseType::UnsupportedTokenType,
_ => RevocationErrorResponseType::Basic(BasicErrorResponseType::Extension(ext)),
},
basic => RevocationErrorResponseType::Basic(basic),
}
}
}
impl AsRef<str> for RevocationErrorResponseType {
fn as_ref(&self) -> &str {
match self {
RevocationErrorResponseType::UnsupportedTokenType => "unsupported_token_type",
RevocationErrorResponseType::Basic(basic) => basic.as_ref(),
}
}
}
impl<'de> serde::Deserialize<'de> for RevocationErrorResponseType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let variant_str = String::deserialize(deserializer)?;
Ok(Self::from_str(&variant_str))
}
}
impl serde::ser::Serialize for RevocationErrorResponseType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
serializer.serialize_str(self.as_ref())
}
}
impl ErrorResponseType for RevocationErrorResponseType {}
impl Debug for RevocationErrorResponseType {
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatterError> {
Display::fmt(self, f)
}
}
impl Display for RevocationErrorResponseType {
fn fmt(&self, f: &mut Formatter) -> Result<(), FormatterError> {
write!(f, "{}", self.as_ref())
}
}