use std::{borrow::Cow, ops::Deref};
use gdp_rs::{proven::ProvenError, Proven};
use picky::jose::jwk::Jwk;
use serde::{Deserialize, Serialize};
pub use self::predicate::InvalidDPoPProofJwk;
use self::predicate::IsValidDPoPProofJwk;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct DPoPProofJwk<'inner>(Proven<Cow<'inner, Jwk>, IsValidDPoPProofJwk>);
impl<'inner> TryFrom<Cow<'inner, Jwk>> for DPoPProofJwk<'inner> {
type Error = ProvenError<Cow<'inner, Jwk>, InvalidDPoPProofJwk>;
#[inline]
fn try_from(jwk: Cow<'inner, Jwk>) -> Result<Self, Self::Error> {
Ok(Self(Proven::try_new(jwk)?))
}
}
impl TryFrom<Jwk> for DPoPProofJwk<'static> {
type Error = ProvenError<Jwk, InvalidDPoPProofJwk>;
#[inline]
fn try_from(jwk: Jwk) -> Result<Self, Self::Error> {
Ok(Self(Proven::try_new(Cow::Owned(jwk)).map_err(|e| {
ProvenError {
error: e.error,
subject: (e.subject as Cow<Jwk>).into_owned(),
}
})?))
}
}
impl<'inner> From<DPoPProofJwk<'inner>> for Cow<'inner, Jwk> {
#[inline]
fn from(alg: DPoPProofJwk<'inner>) -> Self {
alg.0.into_subject()
}
}
impl<'inner> From<DPoPProofJwk<'inner>> for Jwk {
#[inline]
fn from(alg: DPoPProofJwk<'inner>) -> Self {
alg.0.into_subject().into_owned()
}
}
impl<'inner> Deref for DPoPProofJwk<'inner> {
type Target = Jwk;
#[inline]
fn deref(&self) -> &Self::Target {
self.0.as_ref()
}
}
impl<'inner> DPoPProofJwk<'inner> {
#[inline]
pub unsafe fn new_unchecked(jwk: Cow<'inner, Jwk>) -> Self {
Self(Proven::new_unchecked(jwk))
}
}
mod predicate {
use std::borrow::{Borrow, Cow};
use gdp_rs::predicate::{Predicate, PurePredicate, SyncEvaluablePredicate};
use picky::jose::jwk::Jwk;
#[derive(Debug)]
pub struct IsValidDPoPProofJwk;
impl<K: Borrow<Jwk>> Predicate<K> for IsValidDPoPProofJwk {
fn label() -> Cow<'static, str> {
"IsValidDPoPProofJwk".into()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
pub enum InvalidDPoPProofJwk {
#[error("JWK Contains a private key.")]
ContainsPrivateKey,
}
impl<K: Borrow<Jwk>> SyncEvaluablePredicate<K> for IsValidDPoPProofJwk {
type EvalError = InvalidDPoPProofJwk;
fn evaluate_for(_jwk: &K) -> Result<(), Self::EvalError> {
Ok(())
}
}
impl<K: Borrow<Jwk>> PurePredicate<K> for IsValidDPoPProofJwk {}
}