solverforge_solver/heuristic/move/
either.rs1use std::fmt::Debug;
9
10use solverforge_core::domain::PlanningSolution;
11use solverforge_scoring::Director;
12
13use super::{ChangeMove, Move, SwapMove};
14
15pub enum EitherMove<S, V> {
20 Change(ChangeMove<S, V>),
21 Swap(SwapMove<S, V>),
22}
23
24impl<S, V: Clone> Clone for EitherMove<S, V> {
25 fn clone(&self) -> Self {
26 match self {
27 Self::Change(m) => Self::Change(m.clone()),
28 Self::Swap(m) => Self::Swap(*m),
29 }
30 }
31}
32
33impl<S, V: Copy> Copy for EitherMove<S, V> {}
34
35impl<S, V: Debug> Debug for EitherMove<S, V> {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 Self::Change(m) => m.fmt(f),
39 Self::Swap(m) => m.fmt(f),
40 }
41 }
42}
43
44impl<S, V> Move<S> for EitherMove<S, V>
45where
46 S: PlanningSolution,
47 V: Clone + PartialEq + Send + Sync + Debug + 'static,
48{
49 fn is_doable<D: Director<S>>(&self, score_director: &D) -> bool {
50 match self {
51 Self::Change(m) => m.is_doable(score_director),
52 Self::Swap(m) => m.is_doable(score_director),
53 }
54 }
55
56 fn do_move<D: Director<S>>(&self, score_director: &mut D) {
57 match self {
58 Self::Change(m) => m.do_move(score_director),
59 Self::Swap(m) => m.do_move(score_director),
60 }
61 }
62
63 fn descriptor_index(&self) -> usize {
64 match self {
65 Self::Change(m) => m.descriptor_index(),
66 Self::Swap(m) => m.descriptor_index(),
67 }
68 }
69
70 fn entity_indices(&self) -> &[usize] {
71 match self {
72 Self::Change(m) => m.entity_indices(),
73 Self::Swap(m) => m.entity_indices(),
74 }
75 }
76
77 fn variable_name(&self) -> &str {
78 match self {
79 Self::Change(m) => m.variable_name(),
80 Self::Swap(m) => m.variable_name(),
81 }
82 }
83}