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}