#[derive(Clone, Debug, Default)]
pub struct Rlimit {
count: u64,
limit: u64,
}
impl Rlimit {
pub fn new() -> Self {
Self::default()
}
pub fn with_limit(limit: u64) -> Self {
Self { count: 0, limit }
}
pub fn set_limit(&mut self, limit: u64) {
self.limit = limit;
}
pub fn limit(&self) -> u64 {
self.limit
}
pub fn count(&self) -> u64 {
self.count
}
pub fn exhausted(&self) -> bool {
self.limit != 0 && self.count >= self.limit
}
pub fn inc(&mut self) -> bool {
self.inc_by(1)
}
pub fn inc_by(&mut self, n: u64) -> bool {
self.count = self.count.saturating_add(n);
!self.exhausted()
}
pub fn reset(&mut self) {
self.count = 0;
}
}
#[cfg(test)]
mod tests {
use super::Rlimit;
#[test]
fn unlimited_never_exhausts() {
let mut r = Rlimit::new();
for _ in 0..1000 {
assert!(r.inc());
}
assert!(!r.exhausted());
assert_eq!(r.count(), 1000);
}
#[test]
fn limited_exhausts_at_ceiling() {
let mut r = Rlimit::with_limit(3);
assert!(r.inc()); assert!(r.inc()); assert!(!r.inc()); assert!(r.exhausted());
assert!(!r.inc()); }
#[test]
fn inc_by_and_reset() {
let mut r = Rlimit::with_limit(10);
assert!(r.inc_by(4));
assert!(!r.inc_by(20)); assert!(r.exhausted());
r.reset();
assert!(!r.exhausted());
assert_eq!(r.count(), 0);
}
}