Skip to main content

solverforge_solver/builder/context/
model.rs

1use std::fmt;
2use std::marker::PhantomData;
3
4use super::{
5    ConflictRepairProviderEntry, ListVariableContext, ScalarGroupContext, ScalarVariableContext,
6};
7
8pub enum VariableContext<S, V, DM, IDM> {
9    Scalar(ScalarVariableContext<S>),
10    List(ListVariableContext<S, V, DM, IDM>),
11}
12
13impl<S, V, DM: Clone, IDM: Clone> Clone for VariableContext<S, V, DM, IDM> {
14    fn clone(&self) -> Self {
15        match self {
16            Self::Scalar(variable) => Self::Scalar(*variable),
17            Self::List(variable) => Self::List(variable.clone()),
18        }
19    }
20}
21
22impl<S, V, DM: fmt::Debug, IDM: fmt::Debug> fmt::Debug for VariableContext<S, V, DM, IDM> {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        match self {
25            Self::Scalar(variable) => variable.fmt(f),
26            Self::List(variable) => variable.fmt(f),
27        }
28    }
29}
30
31pub struct ModelContext<S, V, DM, IDM> {
32    variables: Vec<VariableContext<S, V, DM, IDM>>,
33    scalar_groups: Vec<ScalarGroupContext<S>>,
34    conflict_repair_providers: Vec<ConflictRepairProviderEntry<S>>,
35    _phantom: PhantomData<(fn() -> S, fn() -> V)>,
36}
37
38impl<S, V, DM: Clone, IDM: Clone> Clone for ModelContext<S, V, DM, IDM> {
39    fn clone(&self) -> Self {
40        Self {
41            variables: self.variables.clone(),
42            scalar_groups: self.scalar_groups.clone(),
43            conflict_repair_providers: self.conflict_repair_providers.clone(),
44            _phantom: PhantomData,
45        }
46    }
47}
48
49impl<S, V, DM, IDM> ModelContext<S, V, DM, IDM> {
50    pub fn new(variables: Vec<VariableContext<S, V, DM, IDM>>) -> Self {
51        Self {
52            variables,
53            scalar_groups: Vec::new(),
54            conflict_repair_providers: Vec::new(),
55            _phantom: PhantomData,
56        }
57    }
58
59    pub fn with_scalar_groups(mut self, groups: Vec<ScalarGroupContext<S>>) -> Self {
60        self.scalar_groups = groups;
61        self
62    }
63
64    pub fn with_conflict_repair_providers(
65        mut self,
66        providers: Vec<ConflictRepairProviderEntry<S>>,
67    ) -> Self {
68        self.conflict_repair_providers = providers;
69        self
70    }
71
72    pub fn variables(&self) -> &[VariableContext<S, V, DM, IDM>] {
73        &self.variables
74    }
75
76    pub fn scalar_groups(&self) -> &[ScalarGroupContext<S>] {
77        &self.scalar_groups
78    }
79
80    pub fn conflict_repair_providers(&self) -> &[ConflictRepairProviderEntry<S>] {
81        &self.conflict_repair_providers
82    }
83
84    pub fn is_empty(&self) -> bool {
85        self.variables.is_empty()
86    }
87
88    pub fn has_list_variables(&self) -> bool {
89        self.variables
90            .iter()
91            .any(|variable| matches!(variable, VariableContext::List(_)))
92    }
93
94    pub fn scalar_variables(&self) -> impl Iterator<Item = &ScalarVariableContext<S>> {
95        self.variables.iter().filter_map(|variable| match variable {
96            VariableContext::Scalar(ctx) => Some(ctx),
97            VariableContext::List(_) => None,
98        })
99    }
100
101    pub fn list_variables(&self) -> impl Iterator<Item = &ListVariableContext<S, V, DM, IDM>> {
102        self.variables.iter().filter_map(|variable| match variable {
103            VariableContext::List(ctx) => Some(ctx),
104            VariableContext::Scalar(_) => None,
105        })
106    }
107}
108
109impl<S, V, DM: fmt::Debug, IDM: fmt::Debug> fmt::Debug for ModelContext<S, V, DM, IDM> {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        f.debug_struct("ModelContext")
112            .field("variables", &self.variables)
113            .field("scalar_groups", &self.scalar_groups)
114            .field("conflict_repair_providers", &self.conflict_repair_providers)
115            .finish()
116    }
117}