use std::pin::Pin;
use crate::{
BoxedError,
crypto::{
KeyMatchStrength,
refreshable::Refreshable,
verifier::{JwsVerifier, KeyMatch, VerifyError},
},
platform::{MaybeSendFuture, MaybeSendSync},
};
pub struct RefreshableVerifier<V> {
inner: Refreshable<V>,
}
impl<V: std::fmt::Debug> std::fmt::Debug for RefreshableVerifier<V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RefreshableVerifier")
.field("inner", &self.inner)
.finish()
}
}
#[bon::bon]
impl<V: JwsVerifier + std::fmt::Debug + MaybeSendSync + 'static> RefreshableVerifier<V> {
#[builder]
pub async fn new(
factory: impl Fn() -> Pin<Box<dyn MaybeSendFuture<Output = Result<V, BoxedError>>>>
+ MaybeSendSync
+ 'static,
) -> Result<Self, BoxedError> {
let inner = Refreshable::builder().factory(factory).build().await?;
Ok(Self { inner })
}
pub async fn refresh(&self) -> Result<bool, crate::BoxedError> {
self.inner.refresh().await
}
}
impl<V: JwsVerifier + std::fmt::Debug + MaybeSendSync + 'static> JwsVerifier
for RefreshableVerifier<V>
{
type Error = V::Error;
fn key_match(&self, key_match: &KeyMatch<'_>) -> Option<KeyMatchStrength> {
self.inner.load().key_match(key_match)
}
async fn verify(
&self,
input: &[u8],
signature: &[u8],
key_match: &KeyMatch<'_>,
) -> Result<(), VerifyError<Self::Error>> {
self.inner
.load_full()
.verify(input, signature, key_match)
.await
}
async fn try_refresh(&self) -> bool {
self.refresh().await.unwrap_or(false)
}
}