bc_envelope_pattern/
quantifier.rs

1use std::ops::RangeBounds;
2
3use crate::{Interval, Reluctance};
4
5/// Defines how many times a pattern may or must match, with an interval and a reluctance.
6#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
7pub struct Quantifier {
8    interval: Interval,
9    reluctance: Reluctance,
10}
11
12impl Quantifier {
13    pub fn new(
14        interval: impl RangeBounds<usize>,
15        reluctance: Reluctance,
16    ) -> Self {
17        let repeat = Interval::new(interval);
18        Self { interval: repeat, reluctance }
19    }
20
21    pub fn min(&self) -> usize { self.interval.min() }
22
23    pub fn max(&self) -> Option<usize> { self.interval.max() }
24
25    pub fn reluctance(&self) -> Reluctance { self.reluctance }
26
27    pub fn contains(&self, count: usize) -> bool {
28        self.interval.contains(count)
29    }
30
31    pub fn is_unbounded(&self) -> bool { self.interval.is_unbounded() }
32}
33
34impl Default for Quantifier {
35    fn default() -> Self { Quantifier::new(1..=1, Reluctance::Greedy) }
36}
37
38impl std::fmt::Display for Quantifier {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        write!(
41            f,
42            "{}{}",
43            self.interval.shorthand_notation(),
44            self.reluctance.suffix()
45        )
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    #[rustfmt::skip]
55    fn test_quantifier_display() {
56        assert_eq!(format!("{}", Quantifier::new(1..=5, Reluctance::Greedy)), "{1,5}");
57        assert_eq!(format!("{}", Quantifier::new(3..=3, Reluctance::Lazy)), "{3}?");
58        assert_eq!(format!("{}", Quantifier::new(2.., Reluctance::Possessive)), "{2,}+");
59        assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Greedy)), "*");
60        assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Lazy)), "*?");
61        assert_eq!(format!("{}", Quantifier::new(0.., Reluctance::Possessive)), "*+");
62        assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Greedy)), "+");
63        assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Lazy)), "+?");
64        assert_eq!(format!("{}", Quantifier::new(1.., Reluctance::Possessive)), "++");
65        assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Greedy)), "?");
66        assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Lazy)), "??");
67        assert_eq!(format!("{}", Quantifier::new(0..=1, Reluctance::Possessive)), "?+");
68    }
69}