vrp_core/
macros.rs

1//! Provides some useful macros to avoid repetitive code.
2
3/// A macro to define a custom property on [crate::models::Extras].
4#[macro_export]
5macro_rules! custom_extra_property {
6    ($name:ident typeof $type:ty $(: $gen:ident)?) => {
7        paste::paste! {
8            #[doc = " Extends [Extras] within a new ["[<$name ExtraProperty>]"]."]
9            pub trait [<$name ExtraProperty>] {
10                #[doc = " Gets "$name " property as a shared reference."]
11                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<std::sync::Arc<$type>>;
12
13                #[doc = " Sets "$name " property using a shared reference."]
14                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: std::sync::Arc<$type>) -> &mut Self;
15            }
16
17            // Define a dummy struct type which is used as a key.
18            struct [<$name ExtraPropertyKey>];
19            impl [<$name ExtraProperty>] for Extras {
20
21                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<std::sync::Arc<$type>> {
22                    self.get_value::<[<$name ExtraPropertyKey>], _>()
23                }
24
25                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: std::sync::Arc<$type>) -> &mut Self {
26                    self.set_value::<[<$name ExtraPropertyKey>], _>(value);
27                    self
28                }
29            }
30        }
31    };
32}
33
34/// A macro to define a custom solution state on [crate::construction::heuristics::SolutionState].
35#[macro_export]
36macro_rules! custom_solution_state {
37    ($name:ident typeof $type:ty $(: $gen:ident)?) => {
38        paste::paste! {
39            #[doc = " Extends [SolutionState] within a new ["[<$name SolutionState>]"]."]
40            pub trait [<$name SolutionState>] {
41                #[doc = " Gets "$name " property."]
42                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type>;
43                #[doc = " Sets "$name " property."]
44                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type) -> &mut Self;
45            }
46
47            // Define a dummy struct type which is used as a key.
48            struct [<$name SolutionStateKey>];
49            impl [<$name SolutionState>] for SolutionState {
50                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type> {
51                    self.get_value::<[<$name SolutionStateKey>], _>()
52                }
53
54                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type) -> &mut Self {
55                    self.set_value::<[<$name SolutionStateKey>], _>(value);
56                    self
57                }
58            }
59        }
60    };
61}
62
63/// A macro to define a custom dimension on [crate::models::common::Dimensions].
64#[macro_export]
65macro_rules! custom_dimension {
66    ($name:ident typeof $type:ty $(: $gen:ident)?) => {
67        paste::paste! {
68            #[doc = " Extends [Dimensions] within a new ["[<$name Dimension>]"]."]
69            pub trait [<$name Dimension>] {
70                #[doc = " Gets "$name " property."]
71                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type>;
72                #[doc = " Sets "$name " property."]
73                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type) -> &mut Self;
74            }
75
76            // Define a dummy struct type which is used as a key.
77            struct [<$name DimensionKey>];
78            impl [<$name Dimension>] for Dimensions {
79                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type> {
80                    self.get_value::<[<$name DimensionKey>], _>()
81                }
82
83                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type) -> &mut Self {
84                    self.set_value::<[<$name DimensionKey>], _>(value);
85                    self
86                }
87            }
88        }
89    };
90}
91
92/// A macro to define a custom activity state on [crate::construction::heuristics::RouteState].
93#[macro_export]
94macro_rules! custom_activity_state {
95    ($name:ident typeof $type:ty $(: $gen:ident)?) => {
96        paste::paste! {
97            #[doc = " Extends [RouteState] within a new ["[<$name ActivityState>]"]."]
98            pub trait [<$name ActivityState>] {
99                #[doc = " Gets `"$name "` activity state."]
100                fn [<get_ $name:snake:lower _at>]$(<$type : $gen>)?(&self, activity_idx: usize) -> Option<&$type>;
101                #[doc = " Sets `"$name "` activity states."]
102                fn [<set_ $name:snake:lower _states>]$(<$type : $gen>)?(&mut self, values: Vec<$type>);
103            }
104
105            // Define a dummy struct type which is used as a key.
106            struct [<$name ActivityStateKey>];
107            impl [<$name ActivityState>] for RouteState {
108                fn [<get_ $name:snake:lower _at>]$(<$type : $gen>)?(&self, activity_idx: usize) -> Option<&$type> {
109                    self.get_activity_state::<[<$name ActivityStateKey>], _>(activity_idx)
110                }
111
112                fn [<set_ $name:snake:lower _states>]$(<$type : $gen>)?(&mut self, values: Vec<$type>) {
113                    self.set_activity_states::<[<$name ActivityStateKey>], _>(values);
114                }
115            }
116        }
117    };
118}
119
120/// A macro to define custom route state on [crate::construction::heuristics::RouteState].
121#[macro_export]
122macro_rules! custom_tour_state {
123    ($name:ident typeof $type:ty $(: $gen:ident)?) => {
124        paste::paste! {
125            #[doc = " Extends [RouteState] within a new ["[<$name TourState>]"]."]
126            pub trait [<$name TourState>] {
127                #[doc = " Gets `"$name "` tour state."]
128                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type>;
129                #[doc = " Sets `"$name "` tour state."]
130                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type);
131
132                #[doc = " Removes `"$name "` tour state."]
133                #[allow(dead_code)]
134                fn [<remove_ $name:snake:lower>](&mut self) -> bool;
135            }
136
137            // Define a dummy struct type which is used as a key
138            struct [<$name TourStateKey>];
139            impl [<$name TourState>] for RouteState {
140                fn [<get_ $name:snake:lower>]$(<$type : $gen>)?(&self) -> Option<&$type> {
141                    self.get_tour_state::<[<$name TourStateKey>], _>()
142                }
143
144                fn [<set_ $name:snake:lower>]$(<$type : $gen>)?(&mut self, value: $type) {
145                    self.set_tour_state::<[<$name TourStateKey>], _>(value);
146                }
147
148                fn [<remove_ $name:snake:lower>](&mut self) -> bool {
149                    self.remove_tour_state::<[<$name TourStateKey>]>()
150                }
151            }
152        }
153    };
154}
155
156/// A macro to define custom route intervals state used within [crate::construction::enablers::RouteIntervals].
157#[macro_export]
158macro_rules! custom_route_intervals_state {
159    // visibility modifier is provided
160    ($(#[$meta:meta])* $vis:vis $name:ident) => {
161        paste::paste! {
162            custom_tour_state!($name typeof Vec<(usize, usize)>);
163            $(#[$meta])*
164            /// Provides access to route intervals implementation.
165            $vis struct [<$name State>];
166            impl RouteIntervalsState for [<$name State>] {
167                fn get_route_intervals<'a>(&self, route_state: &'a RouteState) -> Option<&'a Vec<(usize, usize)>> {
168                    route_state.[<get_ $name:snake:lower>]()
169                }
170
171                fn set_route_intervals(&self, route_state: &mut RouteState, values: Vec<(usize, usize)>) {
172                    route_state.[<set_ $name:snake:lower>](values);
173                }
174            }
175        }
176    };
177
178    // no visibility modifier is provided
179    ($(#[$meta:meta])* $name:ident) => {
180        custom_route_intervals_state!($(#[$meta])* pub(crate) $name);
181    };
182}