ommx/
decision_variable.rs

1use crate::{parse::*, v1, Bound};
2use derive_more::{Deref, From};
3use std::collections::HashMap;
4
5/// ID for decision variable and parameter.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, From, Deref)]
7pub struct VariableID(u64);
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub enum Kind {
11    Continuous,
12    Integer,
13    Binary,
14    SemiContinuous,
15    SemiInteger,
16}
17
18impl Parse for v1::decision_variable::Kind {
19    type Output = Kind;
20    type Context = ();
21    fn parse(self, _: &Self::Context) -> Result<Self::Output, ParseError> {
22        use v1::decision_variable::Kind::*;
23        match self {
24            Unspecified => Err(RawParseError::UnspecifiedEnum {
25                enum_name: "ommx.v1.decision_variable.Kind",
26            }
27            .into()),
28            Continuous => Ok(Kind::Continuous),
29            Integer => Ok(Kind::Integer),
30            Binary => Ok(Kind::Binary),
31            SemiContinuous => Ok(Kind::SemiContinuous),
32            SemiInteger => Ok(Kind::SemiInteger),
33        }
34    }
35}
36
37#[derive(Debug, Clone, PartialEq)]
38pub struct DecisionVariable {
39    pub id: VariableID,
40    pub kind: Kind,
41    pub bound: Bound,
42
43    pub substituted_value: Option<f64>,
44
45    pub name: Option<String>,
46    pub subscripts: Vec<i64>,
47    pub parameters: HashMap<String, String>,
48    pub description: Option<String>,
49}
50
51impl Parse for v1::DecisionVariable {
52    type Output = DecisionVariable;
53    type Context = ();
54    fn parse(self, _: &Self::Context) -> Result<Self::Output, ParseError> {
55        let message = "ommx.v1.DecisionVariable";
56        Ok(DecisionVariable {
57            id: VariableID(self.id),
58            kind: self.kind().parse_as(&(), message, "kind")?,
59            bound: self
60                .bound
61                .unwrap_or_default()
62                .parse_as(&(), message, "bound")?,
63            substituted_value: self.substituted_value,
64            name: self.name,
65            subscripts: self.subscripts,
66            parameters: self.parameters,
67            description: self.description,
68        })
69    }
70}
71
72impl Parse for Vec<v1::DecisionVariable> {
73    type Output = HashMap<VariableID, DecisionVariable>;
74    type Context = ();
75    fn parse(self, _: &Self::Context) -> Result<Self::Output, ParseError> {
76        let mut decision_variables = HashMap::new();
77        for v in self {
78            let v: DecisionVariable = v.parse(&())?;
79            let id = v.id;
80            if decision_variables.insert(id, v).is_some() {
81                return Err(RawParseError::DuplicatedVariableID { id }.into());
82            }
83        }
84        Ok(decision_variables)
85    }
86}