rbe/
cardinality.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use serde_derive::Deserialize;
use serde_derive::Serialize;

use crate::Max;
use crate::Min;
use std::cmp;
use std::fmt;

#[derive(PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
pub struct Cardinality {
    pub min: Min,
    pub max: Max,
}

impl Cardinality {
    pub fn from(min: Min, max: Max) -> Cardinality {
        Cardinality { min, max }
    }

    pub fn nullable(&self) -> bool {
        self.min == Min { value: 0 }
    }

    pub fn is_0_0(&self) -> bool {
        self.min == Min { value: 0 } && self.max == Max::IntMax(0)
    }

    pub fn is_1_1(&self) -> bool {
        self.min == Min { value: 1 } && self.max == Max::IntMax(1)
    }

    pub fn is_star(&self) -> bool {
        self.min == Min { value: 0 } && self.max == Max::Unbounded
    }

    pub fn is_plus(&self) -> bool {
        self.min == Min { value: 1 } && self.max == Max::Unbounded
    }

    pub fn contains(&self, n: usize) -> bool {
        n >= self.min.value && self.max.greater_or_equal(n)
    }

    pub fn minus(&self, n: usize) -> Cardinality {
        let min = if self.min.value > n {
            self.min.value - n
        } else {
            0
        };
        Cardinality {
            min: Min {
                value: cmp::max(min, 0),
            },
            max: self.max.minus(n),
        }
    }
}

impl fmt::Display for Cardinality {
    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
        match (&self.min, &self.max) {
            (Min { value: 0 }, Max::IntMax(1)) => write!(dest, "?"),
            (Min { value: 0 }, Max::Unbounded) => write!(dest, "*"),
            (Min { value: 1 }, Max::Unbounded) => write!(dest, "+"),
            (min, Max::Unbounded) => write!(dest, "{{{},}}", min.value),
            (min, max) => write!(dest, "{{{}, {}}}", min.value, max),
        }
    }
}

impl fmt::Debug for Cardinality {
    fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
        match (&self.min, &self.max) {
            (Min { value: 0 }, Max::IntMax(1)) => write!(dest, "?"),
            (Min { value: 0 }, Max::Unbounded) => write!(dest, "*"),
            (Min { value: 1 }, Max::Unbounded) => write!(dest, "+"),
            (min, Max::Unbounded) => write!(dest, "{{{},}}", min.value),
            (min, max) => write!(dest, "{{{}, {}}}", min.value, max),
        }
    }
}