use serde::{de::Visitor, Deserialize};
use std::{fmt, future::Future, pin::Pin};
use url::Url;
pub type DynErr = Box<dyn std::error::Error + Send + Sync>;
pub type DynFut<T> = Pin<Box<dyn Future<Output = T> + Send>>;
pub type DynRes<T> = Result<T, DynErr>;
pub type DynFutRes<T> = DynFut<DynRes<T>>;
#[derive(Clone, Copy, Deserialize, PartialEq, Eq)]
pub enum ResponseMode {
Fragment,
FormPost,
}
impl ResponseMode {
pub fn as_str(&self) -> &'static str {
match self {
ResponseMode::Fragment => "fragment",
ResponseMode::FormPost => "form_post",
}
}
}
impl Default for ResponseMode {
fn default() -> Self {
ResponseMode::FormPost
}
}
#[derive(Deserialize)]
pub struct DiscoveryDoc {
pub jwks_uri: Url,
pub authorization_endpoint: Url,
}
pub fn deserialize_timestamp<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
D: serde::Deserializer<'de>,
{
struct TimestampVisitor;
impl<'de> Visitor<'de> for TimestampVisitor {
type Value = u64;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a positive number")
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v)
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v as u64)
}
}
deserializer.deserialize_any(TimestampVisitor)
}
pub mod base64url {
pub use base64::prelude::*;
#[inline]
pub fn encode<T: ?Sized + AsRef<[u8]>>(data: &T) -> String {
BASE64_URL_SAFE_NO_PAD.encode(data)
}
#[inline]
pub fn decode<T: ?Sized + AsRef<[u8]>>(data: &T) -> Result<Vec<u8>, base64::DecodeError> {
BASE64_URL_SAFE_NO_PAD.decode(data)
}
}