1#![deny(missing_docs)]
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum TravelMode {
11 Pedestrian,
13 Vehicle,
15 Bicycle,
17 Transit,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
23pub struct AllowedModes(u8);
24
25impl AllowedModes {
26 const PEDESTRIAN: u8 = 1 << 0;
27 const VEHICLE: u8 = 1 << 1;
28 const BICYCLE: u8 = 1 << 2;
29 const TRANSIT: u8 = 1 << 3;
30
31 pub fn none() -> Self {
33 Self(0)
34 }
35
36 pub fn all() -> Self {
38 Self(Self::PEDESTRIAN | Self::VEHICLE | Self::BICYCLE | Self::TRANSIT)
39 }
40
41 pub fn pedestrian_only() -> Self {
43 Self(Self::PEDESTRIAN)
44 }
45
46 pub fn vehicular() -> Self {
48 Self(Self::VEHICLE | Self::TRANSIT)
49 }
50
51 pub fn active() -> Self {
53 Self(Self::PEDESTRIAN | Self::BICYCLE)
54 }
55
56 pub fn allows(self, mode: TravelMode) -> bool {
58 let flag = match mode {
59 TravelMode::Pedestrian => Self::PEDESTRIAN,
60 TravelMode::Vehicle => Self::VEHICLE,
61 TravelMode::Bicycle => Self::BICYCLE,
62 TravelMode::Transit => Self::TRANSIT,
63 };
64 self.0 & flag != 0
65 }
66
67 pub fn with_mode(mut self, mode: TravelMode) -> Self {
69 let flag = match mode {
70 TravelMode::Pedestrian => Self::PEDESTRIAN,
71 TravelMode::Vehicle => Self::VEHICLE,
72 TravelMode::Bicycle => Self::BICYCLE,
73 TravelMode::Transit => Self::TRANSIT,
74 };
75 self.0 |= flag;
76 self
77 }
78}
79
80pub mod prelude {
82 pub use crate::{AllowedModes, TravelMode};
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn allowed_modes_helpers_work() {
91 let active = AllowedModes::active();
92 assert!(active.allows(TravelMode::Pedestrian));
93 assert!(active.allows(TravelMode::Bicycle));
94 assert!(!active.allows(TravelMode::Vehicle));
95 assert!(!active.allows(TravelMode::Transit));
96
97 let custom = AllowedModes::none().with_mode(TravelMode::Transit);
98 assert!(custom.allows(TravelMode::Transit));
99 assert!(!custom.allows(TravelMode::Vehicle));
100 }
101}