1
use std::fmt::Display;
2

            
3
use serde::{Deserialize, Serialize};
4

            
5
use crate::ast::domains::{Domain, Range};
6

            
7
/// Represents a decision variable within a computational model.
8
///
9
/// A `DecisionVariable` has a domain that defines the set of values it can take. The domain could be:
10
/// - A boolean domain, meaning the variable can only be `true` or `false`.
11
/// - An integer domain, meaning the variable can only take specific integer values or a range of integers.
12
///
13
/// # Fields
14
/// - `domain`:
15
///   - Type: `Domain`
16
///   - Represents the set of possible values that this decision variable can assume. The domain can be a range of integers
17
///   (IntDomain) or a boolean domain (BoolDomain).
18
///
19
/// # Example
20
///
21
/// use crate::ast::domains::{DecisionVariable, Domain, Range};
22
///
23
/// let bool_var = DecisionVariable::new(Domain::BoolDomain);
24
/// let int_var = DecisionVariable::new(Domain::IntDomain(vec![Range::Bounded(1, 10)]));
25
///
26
/// println!("Boolean Variable: {}", bool_var);
27
/// println!("Integer Variable: {}", int_var);
28

            
29
820
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
30
pub struct DecisionVariable {
31
    pub domain: Domain,
32
}
33
impl DecisionVariable {
34
258
    pub fn new(domain: Domain) -> DecisionVariable {
35
258
        DecisionVariable { domain }
36
258
    }
37
}
38

            
39
impl Display for DecisionVariable {
40
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41
        match &self.domain {
42
            Domain::BoolDomain => write!(f, "bool"),
43
            Domain::IntDomain(ranges) => {
44
                let mut first = true;
45
                for r in ranges {
46
                    if first {
47
                        first = false;
48
                    } else {
49
                        write!(f, " or ")?;
50
                    }
51
                    match r {
52
                        Range::Single(i) => write!(f, "{}", i)?,
53
                        Range::Bounded(i, j) => write!(f, "{}..{}", i, j)?,
54
                    }
55
                }
56
                Ok(())
57
            }
58
        }
59
    }
60
}