use core::time::Duration;
#[must_use]
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Decision {
Allow,
Deny {
retry_after: Duration,
},
}
impl Decision {
#[must_use]
pub const fn is_allow(&self) -> bool {
matches!(self, Self::Allow)
}
#[must_use]
pub const fn is_deny(&self) -> bool {
!self.is_allow()
}
#[must_use]
pub const fn retry_after(&self) -> Option<Duration> {
match self {
Self::Deny { retry_after } => Some(*retry_after),
_ => None,
}
}
}
impl From<better_bucket::Decision> for Decision {
fn from(decision: better_bucket::Decision) -> Self {
match decision {
better_bucket::Decision::Allowed => Self::Allow,
better_bucket::Decision::Denied { retry_after } => Self::Deny { retry_after },
_ => Self::Deny {
retry_after: Duration::MAX,
},
}
}
}
#[cfg(test)]
mod tests {
use super::Decision;
use core::time::Duration;
#[test]
fn test_allow_predicates() {
let allow = Decision::Allow;
assert!(allow.is_allow());
assert!(!allow.is_deny());
assert_eq!(allow.retry_after(), None);
}
#[test]
fn test_deny_predicates() {
let deny = Decision::Deny {
retry_after: Duration::from_secs(2),
};
assert!(deny.is_deny());
assert!(!deny.is_allow());
assert_eq!(deny.retry_after(), Some(Duration::from_secs(2)));
}
#[test]
fn test_from_better_bucket_allowed_maps_to_allow() {
assert_eq!(
Decision::from(better_bucket::Decision::Allowed),
Decision::Allow
);
}
#[test]
fn test_from_better_bucket_denied_carries_retry_after() {
let upstream = better_bucket::Decision::Denied {
retry_after: Duration::from_millis(500),
};
assert_eq!(
Decision::from(upstream),
Decision::Deny {
retry_after: Duration::from_millis(500)
}
);
}
}