solverforge_solver/builder/context/
model.rs1use 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}