use std::time::Duration;
use bounded_integer::BoundedU8;
use serde::{Deserialize, Serialize};
pub type ConcurrencyLimit = BoundedU8<1, 255>;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Default)]
pub enum StalePolicy {
#[default]
Return,
Revalidate,
OffloadRevalidate,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Default)]
pub struct CacheBehaviorPolicy {
#[serde(default)]
pub stale: StalePolicy,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
pub struct EnabledCacheConfig {
#[serde(default, with = "humantime_serde")]
pub ttl: Option<Duration>,
#[serde(default, with = "humantime_serde")]
pub stale: Option<Duration>,
#[serde(default)]
pub policy: CacheBehaviorPolicy,
pub concurrency: Option<ConcurrencyLimit>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub enum PolicyConfig {
Enabled(EnabledCacheConfig),
Disabled,
}
impl Default for PolicyConfig {
fn default() -> Self {
Self::Enabled(EnabledCacheConfig::default())
}
}
impl PolicyConfig {
pub fn builder() -> PolicyConfigBuilder {
PolicyConfigBuilder::default()
}
pub fn disabled() -> Self {
Self::Disabled
}
}
#[derive(Debug, Clone, Default)]
pub struct PolicyConfigBuilder {
ttl: Option<Duration>,
stale: Option<Duration>,
stale_policy: StalePolicy,
concurrency: Option<ConcurrencyLimit>,
}
impl PolicyConfigBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn ttl(self, ttl: Duration) -> Self {
Self {
ttl: Some(ttl),
..self
}
}
pub fn stale(self, stale: Duration) -> Self {
Self {
stale: Some(stale),
..self
}
}
pub fn stale_policy(self, policy: StalePolicy) -> Self {
Self {
stale_policy: policy,
..self
}
}
pub fn concurrency(self, limit: ConcurrencyLimit) -> Self {
Self {
concurrency: Some(limit),
..self
}
}
pub fn build(self) -> PolicyConfig {
PolicyConfig::Enabled(EnabledCacheConfig {
ttl: self.ttl,
stale: self.stale,
policy: CacheBehaviorPolicy {
stale: self.stale_policy,
},
concurrency: self.concurrency,
})
}
}