use super::PolicyError;
pub trait RuleLimitedPolicy {
fn max_limit(&self) -> usize;
fn current_count(&self) -> usize;
fn check_limit(&self, additional: usize) -> Result<(), PolicyError> {
let max = self.max_limit();
if max == 0 {
return Ok(());
}
let total = self.current_count().saturating_add(additional);
if total > max {
return Err(PolicyError::TooManyRules {
requested: total,
maximum: max,
});
}
Ok(())
}
fn check_total(&self, total: usize) -> Result<(), PolicyError> {
let max = self.max_limit();
if max == 0 {
return Ok(());
}
if total > max {
return Err(PolicyError::TooManyRules {
requested: total,
maximum: max,
});
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestPolicy {
max_rules: usize,
current_count: usize,
}
impl RuleLimitedPolicy for TestPolicy {
fn max_limit(&self) -> usize {
self.max_rules
}
fn current_count(&self) -> usize {
self.current_count
}
}
#[test]
fn test_no_limit() {
let policy = TestPolicy {
max_rules: 0,
current_count: 1_000_000,
};
assert!(policy.check_limit(1_000_000).is_ok());
assert!(policy.check_total(999_999_999).is_ok());
}
#[test]
fn test_within_limit() {
let policy = TestPolicy {
max_rules: 100,
current_count: 50,
};
assert!(policy.check_limit(30).is_ok());
assert!(policy.check_limit(50).is_ok());
}
#[test]
fn test_exact_limit() {
let policy = TestPolicy {
max_rules: 100,
current_count: 90,
};
assert!(policy.check_limit(10).is_ok());
}
#[test]
fn test_exceed_limit() {
let policy = TestPolicy {
max_rules: 100,
current_count: 90,
};
match policy.check_limit(11) {
Err(PolicyError::TooManyRules { requested, maximum }) => {
assert_eq!(requested, 101);
assert_eq!(maximum, 100);
}
_ => panic!("expected TooManyRules error"),
}
}
#[test]
fn test_check_total_within() {
let policy = TestPolicy {
max_rules: 1000,
current_count: 0,
};
assert!(policy.check_total(500).is_ok());
assert!(policy.check_total(1000).is_ok());
}
#[test]
fn test_check_total_exceed() {
let policy = TestPolicy {
max_rules: 1000,
current_count: 0,
};
match policy.check_total(1001) {
Err(PolicyError::TooManyRules { requested, maximum }) => {
assert_eq!(requested, 1001);
assert_eq!(maximum, 1000);
}
_ => panic!("expected TooManyRules error"),
}
}
}