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