use http_cache_semantics::CachePolicy;
use jsonwebtoken::jwk::JwkSet;
use crate::_prelude::*;
#[derive(Clone, Debug)]
pub struct CachePayload {
pub jwks: Arc<JwkSet>,
pub policy: CachePolicy,
pub etag: Option<String>,
pub last_modified: Option<DateTime<Utc>>,
pub last_refresh_at: DateTime<Utc>,
pub expires_at: Instant,
pub next_refresh_at: Instant,
pub stale_deadline: Option<Instant>,
pub retry_backoff: Option<Duration>,
pub error_count: u32,
}
impl CachePayload {
pub fn is_expired(&self, now: Instant) -> bool {
now >= self.expires_at
}
pub fn can_serve_stale(&self, now: Instant) -> bool {
self.stale_deadline.map(|deadline| now <= deadline).unwrap_or(false)
}
pub fn bump_error(&mut self, backoff: Option<Duration>) {
self.error_count = self.error_count.saturating_add(1);
self.retry_backoff = backoff;
}
pub fn reset_failures(&mut self) {
self.error_count = 0;
self.retry_backoff = None;
}
}
#[derive(Clone, Debug)]
pub enum CacheState {
Empty,
Loading,
Ready(CachePayload),
Refreshing(CachePayload),
}
impl CacheState {
pub fn payload(&self) -> Option<&CachePayload> {
match self {
CacheState::Ready(payload) | CacheState::Refreshing(payload) => Some(payload),
_ => None,
}
}
pub fn payload_mut(&mut self) -> Option<&mut CachePayload> {
match self {
CacheState::Ready(payload) | CacheState::Refreshing(payload) => Some(payload),
_ => None,
}
}
pub fn is_usable(&self) -> bool {
matches!(self, CacheState::Ready(_) | CacheState::Refreshing(_))
}
}