rbe/
cardinality.rs

1use serde::{Deserialize, Serialize};
2
3use crate::Max;
4use crate::Min;
5use std::cmp;
6use std::fmt;
7
8#[derive(PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
9pub struct Cardinality {
10    pub min: Min,
11    pub max: Max,
12}
13
14impl Cardinality {
15    pub fn from(min: Min, max: Max) -> Cardinality {
16        Cardinality { min, max }
17    }
18
19    pub fn nullable(&self) -> bool {
20        self.min == Min { value: 0 }
21    }
22
23    pub fn is_0_0(&self) -> bool {
24        self.min == Min { value: 0 } && self.max == Max::IntMax(0)
25    }
26
27    pub fn is_1_1(&self) -> bool {
28        self.min == Min { value: 1 } && self.max == Max::IntMax(1)
29    }
30
31    pub fn is_star(&self) -> bool {
32        self.min == Min { value: 0 } && self.max == Max::Unbounded
33    }
34
35    pub fn is_plus(&self) -> bool {
36        self.min == Min { value: 1 } && self.max == Max::Unbounded
37    }
38
39    pub fn contains(&self, n: usize) -> bool {
40        n >= self.min.value && self.max.greater_or_equal(n)
41    }
42
43    pub fn minus(&self, n: usize) -> Cardinality {
44        let min = if self.min.value > n {
45            self.min.value - n
46        } else {
47            0
48        };
49        Cardinality {
50            min: Min {
51                value: cmp::max(min, 0),
52            },
53            max: self.max.minus(n),
54        }
55    }
56}
57
58impl fmt::Display for Cardinality {
59    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
60        match (&self.min, &self.max) {
61            (Min { value: 0 }, Max::IntMax(1)) => write!(dest, "?"),
62            (Min { value: 0 }, Max::Unbounded) => write!(dest, "*"),
63            (Min { value: 1 }, Max::Unbounded) => write!(dest, "+"),
64            (min, Max::Unbounded) => write!(dest, "{{{},}}", min.value),
65            (min, max) => write!(dest, "{{{}, {}}}", min.value, max),
66        }
67    }
68}
69
70impl fmt::Debug for Cardinality {
71    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
72        match (&self.min, &self.max) {
73            (Min { value: 0 }, Max::IntMax(1)) => write!(dest, "?"),
74            (Min { value: 0 }, Max::Unbounded) => write!(dest, "*"),
75            (Min { value: 1 }, Max::Unbounded) => write!(dest, "+"),
76            (min, Max::Unbounded) => write!(dest, "{{{},}}", min.value),
77            (min, max) => write!(dest, "{{{}, {}}}", min.value, max),
78        }
79    }
80}