use std::{borrow::Cow, pin::Pin, sync::Arc};
use crate::{
BoxedError,
crypto::signer::{JwsSigner, symmetric::JwsSignerSelector},
platform::{MaybeSendFuture, MaybeSendSync},
};
#[derive(Debug, Clone)]
pub struct BoxedJwsSignerSelector {
inner: Arc<dyn DynJwsSignerSelector>,
}
impl BoxedJwsSignerSelector {
pub fn new<Sgn: JwsSignerSelector + 'static>(signer: Sgn) -> Self {
Self {
inner: Arc::new(signer),
}
}
}
pub(in crate::crypto::signer) trait DynJwsSignerSelector:
std::fmt::Debug + MaybeSendSync
{
fn select_signer(&self) -> BoxedJwsSigner;
}
impl<Sgn: JwsSignerSelector + 'static> DynJwsSignerSelector for Sgn {
fn select_signer(&self) -> BoxedJwsSigner {
BoxedJwsSigner::new(self.select_signer())
}
}
impl JwsSignerSelector for BoxedJwsSignerSelector {
type Signer = BoxedJwsSigner;
fn select_signer(&self) -> Self::Signer {
self.inner.select_signer()
}
}
#[derive(Debug, Clone)]
pub struct BoxedJwsSigner {
inner: Arc<dyn DynJwsSigner>,
}
impl BoxedJwsSigner {
pub fn new<Sgn: JwsSigner + 'static>(signer: Sgn) -> Self {
Self {
inner: Arc::new(signer),
}
}
}
pub(in crate::crypto::signer) trait DynJwsSigner:
std::fmt::Debug + MaybeSendSync
{
fn jws_algorithm(&self) -> Cow<'_, str>;
fn key_id(&self) -> Option<Cow<'_, str>>;
fn sign<'a>(
&'a self,
input: &'a [u8],
) -> Pin<Box<dyn MaybeSendFuture<Output = Result<Vec<u8>, BoxedError>> + 'a>>;
}
impl<Sgn: JwsSigner> DynJwsSigner for Sgn {
fn jws_algorithm(&self) -> Cow<'_, str> {
self.jws_algorithm()
}
fn key_id(&self) -> Option<Cow<'_, str>> {
self.key_id()
}
fn sign<'a>(
&'a self,
input: &'a [u8],
) -> Pin<Box<dyn MaybeSendFuture<Output = Result<Vec<u8>, BoxedError>> + 'a>> {
Box::pin(async { self.sign(input).await.map_err(BoxedError::from_err) })
}
}
impl JwsSigner for BoxedJwsSigner {
type Error = BoxedError;
fn jws_algorithm(&self) -> Cow<'_, str> {
self.inner.jws_algorithm()
}
fn key_id(&self) -> Option<Cow<'_, str>> {
self.inner.key_id()
}
async fn sign(&self, input: &[u8]) -> Result<Vec<u8>, Self::Error> {
self.inner.sign(input).await
}
}