Skip to main content

solverforge_solver/planning/
scalar.rs

1use std::marker::PhantomData;
2
3#[derive(Debug)]
4pub struct ScalarTarget<S> {
5    descriptor_index: usize,
6    variable_name: &'static str,
7    _phantom: PhantomData<fn() -> S>,
8}
9
10impl<S> Clone for ScalarTarget<S> {
11    fn clone(&self) -> Self {
12        *self
13    }
14}
15
16impl<S> Copy for ScalarTarget<S> {}
17
18impl<S> PartialEq for ScalarTarget<S> {
19    fn eq(&self, other: &Self) -> bool {
20        self.descriptor_index == other.descriptor_index && self.variable_name == other.variable_name
21    }
22}
23
24impl<S> Eq for ScalarTarget<S> {}
25
26impl<S> std::hash::Hash for ScalarTarget<S> {
27    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
28        self.descriptor_index.hash(state);
29        self.variable_name.hash(state);
30    }
31}
32
33impl<S> ScalarTarget<S> {
34    #[doc(hidden)]
35    pub const fn from_descriptor_index(
36        descriptor_index: usize,
37        variable_name: &'static str,
38    ) -> Self {
39        Self {
40            descriptor_index,
41            variable_name,
42            _phantom: PhantomData,
43        }
44    }
45
46    #[inline]
47    pub fn set(self, entity_index: usize, to_value: Option<usize>) -> ScalarEdit<S> {
48        ScalarEdit {
49            descriptor_index: self.descriptor_index,
50            entity_index,
51            variable_name: self.variable_name,
52            to_value,
53            _phantom: PhantomData,
54        }
55    }
56
57    #[doc(hidden)]
58    #[inline]
59    pub fn descriptor_index(self) -> usize {
60        self.descriptor_index
61    }
62
63    #[doc(hidden)]
64    #[inline]
65    pub fn variable_name(self) -> &'static str {
66        self.variable_name
67    }
68}
69
70#[derive(Debug)]
71pub struct ScalarEdit<S> {
72    descriptor_index: usize,
73    entity_index: usize,
74    variable_name: &'static str,
75    to_value: Option<usize>,
76    _phantom: PhantomData<fn() -> S>,
77}
78
79impl<S> Clone for ScalarEdit<S> {
80    fn clone(&self) -> Self {
81        *self
82    }
83}
84
85impl<S> Copy for ScalarEdit<S> {}
86
87impl<S> PartialEq for ScalarEdit<S> {
88    fn eq(&self, other: &Self) -> bool {
89        self.descriptor_index == other.descriptor_index
90            && self.entity_index == other.entity_index
91            && self.variable_name == other.variable_name
92            && self.to_value == other.to_value
93    }
94}
95
96impl<S> Eq for ScalarEdit<S> {}
97
98impl<S> std::hash::Hash for ScalarEdit<S> {
99    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
100        self.descriptor_index.hash(state);
101        self.entity_index.hash(state);
102        self.variable_name.hash(state);
103        self.to_value.hash(state);
104    }
105}
106
107impl<S> ScalarEdit<S> {
108    #[doc(hidden)]
109    pub const fn from_descriptor_index(
110        descriptor_index: usize,
111        entity_index: usize,
112        variable_name: &'static str,
113        to_value: Option<usize>,
114    ) -> Self {
115        Self {
116            descriptor_index,
117            entity_index,
118            variable_name,
119            to_value,
120            _phantom: PhantomData,
121        }
122    }
123
124    #[doc(hidden)]
125    #[inline]
126    pub fn descriptor_index(&self) -> usize {
127        self.descriptor_index
128    }
129
130    #[doc(hidden)]
131    #[inline]
132    pub fn entity_index(&self) -> usize {
133        self.entity_index
134    }
135
136    #[doc(hidden)]
137    #[inline]
138    pub fn variable_name(&self) -> &'static str {
139        self.variable_name
140    }
141
142    #[doc(hidden)]
143    #[inline]
144    pub fn to_value(&self) -> Option<usize> {
145        self.to_value
146    }
147}
148
149#[derive(Debug)]
150pub struct ScalarCandidate<S> {
151    reason: &'static str,
152    edits: Vec<ScalarEdit<S>>,
153    construction_slot_key: Option<usize>,
154    construction_entity_order_key: Option<i64>,
155    construction_value_order_key: Option<i64>,
156}
157
158impl<S> Clone for ScalarCandidate<S> {
159    fn clone(&self) -> Self {
160        Self {
161            reason: self.reason,
162            edits: self.edits.clone(),
163            construction_slot_key: self.construction_slot_key,
164            construction_entity_order_key: self.construction_entity_order_key,
165            construction_value_order_key: self.construction_value_order_key,
166        }
167    }
168}
169
170impl<S> PartialEq for ScalarCandidate<S> {
171    fn eq(&self, other: &Self) -> bool {
172        self.reason == other.reason
173            && self.edits == other.edits
174            && self.construction_slot_key == other.construction_slot_key
175            && self.construction_entity_order_key == other.construction_entity_order_key
176            && self.construction_value_order_key == other.construction_value_order_key
177    }
178}
179
180impl<S> Eq for ScalarCandidate<S> {}
181
182impl<S> std::hash::Hash for ScalarCandidate<S> {
183    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
184        self.reason.hash(state);
185        self.edits.hash(state);
186        self.construction_slot_key.hash(state);
187        self.construction_entity_order_key.hash(state);
188        self.construction_value_order_key.hash(state);
189    }
190}
191
192impl<S> ScalarCandidate<S> {
193    pub fn new(reason: &'static str, edits: Vec<ScalarEdit<S>>) -> Self {
194        Self {
195            reason,
196            edits,
197            construction_slot_key: None,
198            construction_entity_order_key: None,
199            construction_value_order_key: None,
200        }
201    }
202
203    pub fn with_construction_slot_key(mut self, key: usize) -> Self {
204        self.construction_slot_key = Some(key);
205        self
206    }
207
208    pub fn with_construction_entity_order_key(mut self, key: i64) -> Self {
209        self.construction_entity_order_key = Some(key);
210        self
211    }
212
213    pub fn with_construction_value_order_key(mut self, key: i64) -> Self {
214        self.construction_value_order_key = Some(key);
215        self
216    }
217
218    #[doc(hidden)]
219    #[inline]
220    pub fn reason(&self) -> &'static str {
221        self.reason
222    }
223
224    #[doc(hidden)]
225    #[inline]
226    pub fn edits(&self) -> &[ScalarEdit<S>] {
227        &self.edits
228    }
229
230    #[doc(hidden)]
231    #[inline]
232    pub fn into_edits(self) -> Vec<ScalarEdit<S>> {
233        self.edits
234    }
235
236    #[doc(hidden)]
237    #[inline]
238    pub fn construction_slot_key(&self) -> Option<usize> {
239        self.construction_slot_key
240    }
241
242    #[doc(hidden)]
243    #[inline]
244    pub fn construction_entity_order_key(&self) -> Option<i64> {
245        self.construction_entity_order_key
246    }
247
248    #[doc(hidden)]
249    #[inline]
250    pub fn construction_value_order_key(&self) -> Option<i64> {
251        self.construction_value_order_key
252    }
253}
254
255#[derive(Debug, Clone, Copy, PartialEq, Eq)]
256pub struct ScalarGroupLimits {
257    pub value_candidate_limit: Option<usize>,
258    pub group_candidate_limit: Option<usize>,
259    pub max_moves_per_step: Option<usize>,
260}
261
262pub type ScalarCandidateProvider<S> = fn(&S, ScalarGroupLimits) -> Vec<ScalarCandidate<S>>;
263
264#[derive(Clone)]
265pub struct ScalarGroup<S> {
266    group_name: &'static str,
267    targets: Vec<ScalarTarget<S>>,
268    candidate_provider: ScalarCandidateProvider<S>,
269}
270
271impl<S> ScalarGroup<S> {
272    pub fn new(
273        group_name: &'static str,
274        targets: Vec<ScalarTarget<S>>,
275        candidate_provider: ScalarCandidateProvider<S>,
276    ) -> Self {
277        Self {
278            group_name,
279            targets,
280            candidate_provider,
281        }
282    }
283
284    #[doc(hidden)]
285    #[inline]
286    pub fn group_name(&self) -> &'static str {
287        self.group_name
288    }
289
290    #[doc(hidden)]
291    #[inline]
292    pub fn targets(&self) -> &[ScalarTarget<S>] {
293        &self.targets
294    }
295
296    #[doc(hidden)]
297    #[inline]
298    pub fn candidate_provider(&self) -> ScalarCandidateProvider<S> {
299        self.candidate_provider
300    }
301}
302
303impl<S> std::fmt::Debug for ScalarGroup<S> {
304    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
305        f.debug_struct("ScalarGroup")
306            .field("group_name", &self.group_name)
307            .field("target_count", &self.targets.len())
308            .finish_non_exhaustive()
309    }
310}