use std::{pin::Pin, sync::Arc};
use crate::{
BoxedError,
crypto::{
refreshable::Refreshable,
signer::{JwsSigner, JwsSignerSelector},
},
platform::{MaybeSendFuture, MaybeSendSync},
};
#[derive(Debug)]
pub struct RefreshableSigner<S> {
inner: Arc<Refreshable<S>>,
}
impl<S> Clone for RefreshableSigner<S> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
#[bon::bon]
impl<S: std::fmt::Debug + MaybeSendSync + 'static> RefreshableSigner<S> {
#[builder]
pub async fn new(
factory: impl Fn() -> Pin<Box<dyn MaybeSendFuture<Output = Result<S, BoxedError>>>>
+ MaybeSendSync
+ 'static,
) -> Result<Self, BoxedError> {
let refreshable = Refreshable::builder().factory(factory).build().await?;
Ok(Self {
inner: Arc::new(refreshable),
})
}
pub async fn refresh(&self) -> Result<bool, crate::BoxedError> {
self.inner.refresh().await
}
}
impl<S> JwsSignerSelector for RefreshableSigner<S>
where
S: JwsSignerSelector + std::fmt::Debug + MaybeSendSync + 'static,
S::Signer: JwsSigner,
{
type Signer = S::Signer;
fn select_signer(&self) -> Self::Signer {
self.inner.load().select_signer()
}
}
impl<S> super::AsymmetricJwsSignerSelector for RefreshableSigner<S>
where
S: super::AsymmetricJwsSignerSelector + std::fmt::Debug + MaybeSendSync + 'static,
S::AsymmetricSigner: super::asymmetric::AsymmetricJwsSigner,
{
type AsymmetricSigner = S::AsymmetricSigner;
fn select_asymmetric_signer(&self) -> Self::AsymmetricSigner {
self.inner.load().select_asymmetric_signer()
}
fn select_asymmetric_signer_by_thumbprint(
&self,
thumbprint: &str,
) -> Option<Self::AsymmetricSigner> {
self.inner
.load()
.select_asymmetric_signer_by_thumbprint(thumbprint)
}
}