use std::ops::RangeBounds;
use crate::{Interval, Reluctance};
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Quantifier {
interval: Interval,
reluctance: Reluctance,
}
impl Quantifier {
pub fn new(
interval: impl RangeBounds<usize>,
reluctance: Reluctance,
) -> Self {
let repeat = Interval::new(interval);
Self { interval: repeat, reluctance }
}
pub fn min(&self) -> usize { self.interval.min() }
pub fn max(&self) -> Option<usize> { self.interval.max() }
pub fn interval(&self) -> Interval { self.interval }
pub fn reluctance(&self) -> Reluctance { self.reluctance }
pub fn contains(&self, count: usize) -> bool {
self.interval.contains(count)
}
pub fn is_unbounded(&self) -> bool { self.interval.is_unbounded() }
}
impl Default for Quantifier {
fn default() -> Self { Quantifier::new(1..=1, Reluctance::Greedy) }
}
impl std::fmt::Display for Quantifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}{}",
self.interval.shorthand_notation(),
self.reluctance.suffix()
)
}
}
impl From<Quantifier> for Interval {
fn from(quantifier: Quantifier) -> Self { quantifier.interval }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[rustfmt::skip]
fn test_quantifier_display() {
assert_eq!(format!("{}", Quantifier::new(1..=5, Reluctance::Greedy)), "{1,5}");
assert_eq!(format!("{}", Quantifier::new(3..=3, Reluctance::Lazy)), "{3}?");
assert_eq!(format!("{}", Quantifier::new(2.., Reluctance::Possessive)), "{2,}+");
assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Greedy)), "*");
assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Lazy)), "*?");
assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Possessive)), "*+");
assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Greedy)), "+");
assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Lazy)), "+?");
assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Possessive)), "++");
assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Greedy)), "?");
assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Lazy)), "??");
assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Possessive)), "?+");
}
}