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