1
use crate::ast::domains::Int;
2
use crate::ast::domains::range::Range;
3
use itertools::Itertools;
4
use polyquine::Quine;
5
use serde::{Deserialize, Serialize};
6
use std::fmt::{Display, Formatter};
7

            
8
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
9
#[path_prefix(conjure_cp::ast)]
10
pub struct SetAttr<A = Int> {
11
    pub size: Range<A>,
12
}
13

            
14
impl<A> SetAttr<A> {
15
    pub fn new(size: Range<A>) -> Self {
16
        Self { size }
17
    }
18

            
19
    pub fn new_min_max_size(min: A, max: A) -> Self {
20
        Self::new(Range::Bounded(min, max))
21
    }
22

            
23
    pub fn new_min_size(min: A) -> Self {
24
        Self::new(Range::UnboundedR(min))
25
    }
26

            
27
    pub fn new_max_size(max: A) -> Self {
28
        Self::new(Range::UnboundedL(max))
29
    }
30

            
31
    pub fn new_size(sz: A) -> Self {
32
        Self::new(Range::Single(sz))
33
    }
34
}
35

            
36
impl<A> Default for SetAttr<A> {
37
    fn default() -> Self {
38
        SetAttr {
39
            size: Range::Unbounded,
40
        }
41
    }
42
}
43

            
44
impl<A: Display> Display for SetAttr<A> {
45
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46
        match &self.size {
47
            Range::Single(x) => write!(f, "(size({x}))"),
48
            Range::Bounded(l, r) => write!(f, "(minSize({l}), maxSize({r}))"),
49
            Range::UnboundedL(r) => write!(f, "(maxSize({r}))"),
50
            Range::UnboundedR(l) => write!(f, "(minSize({l}))"),
51
            Range::Unbounded => write!(f, ""),
52
        }
53
    }
54
}
55

            
56
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
57
#[path_prefix(conjure_cp::ast)]
58
pub struct FuncAttr<A = Int> {
59
    pub size: Range<A>,
60
    pub partiality: PartialityAttr,
61
    pub jectivity: JectivityAttr,
62
}
63

            
64
impl<A: Display> Display for FuncAttr<A> {
65
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
66
        let size_str = match &self.size {
67
            Range::Single(x) => format!("size({x})"),
68
            Range::Bounded(l, r) => format!("minSize({l}), maxSize({r})"),
69
            Range::UnboundedL(r) => format!("maxSize({r})"),
70
            Range::UnboundedR(l) => format!("minSize({l})"),
71
            Range::Unbounded => "".to_string(),
72
        };
73
        let mut strs = [
74
            size_str,
75
            self.partiality.to_string(),
76
            self.jectivity.to_string(),
77
        ]
78
        .iter()
79
        .filter(|s| !s.is_empty())
80
        .join(", ");
81
        if !strs.is_empty() {
82
            strs = format!("({})", strs);
83
        }
84
        write!(f, "{strs}")
85
    }
86
}
87

            
88
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
89
pub enum PartialityAttr {
90
    Total,
91
    Partial,
92
}
93

            
94
impl Display for PartialityAttr {
95
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96
        match self {
97
            PartialityAttr::Total => write!(f, "total"),
98
            PartialityAttr::Partial => write!(f, ""),
99
        }
100
    }
101
}
102

            
103
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Quine)]
104
pub enum JectivityAttr {
105
    None,
106
    Injective,
107
    Surjective,
108
    Bijective,
109
}
110

            
111
impl Display for JectivityAttr {
112
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
113
        match self {
114
            JectivityAttr::None => write!(f, ""),
115
            JectivityAttr::Injective => write!(f, "injective"),
116
            JectivityAttr::Surjective => write!(f, "surjective"),
117
            JectivityAttr::Bijective => write!(f, "bijective"),
118
        }
119
    }
120
}