1
use std::fmt::Display;
2

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

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

            
7
use super::{types::Typeable, ReturnType};
8

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

            
31
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
32
pub struct DecisionVariable {
33
    pub domain: Domain,
34
}
35

            
36
impl DecisionVariable {
37
10492
    pub fn new(domain: Domain) -> DecisionVariable {
38
10492
        DecisionVariable { domain }
39
10492
    }
40
}
41

            
42
impl Typeable for DecisionVariable {
43
    fn return_type(&self) -> Option<ReturnType> {
44
        todo!()
45
    }
46
}
47

            
48
impl Display for DecisionVariable {
49
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50
        match &self.domain {
51
            Domain::BoolDomain => write!(f, "bool"),
52
            Domain::IntDomain(ranges) => {
53
                let mut first = true;
54
                for r in ranges {
55
                    if first {
56
                        first = false;
57
                    } else {
58
                        write!(f, " or ")?;
59
                    }
60
                    match r {
61
                        Range::Single(i) => write!(f, "{}", i)?,
62
                        Range::Bounded(i, j) => write!(f, "{}..{}", i, j)?,
63
                    }
64
                }
65
                Ok(())
66
            }
67
            Domain::DomainReference(name) => write!(f, "{}", name),
68
        }
69
    }
70
}