tosca_controller/
policy.rs1use std::collections::HashMap;
2
3use tosca::hazards::Hazards;
4
5#[derive(Debug, PartialEq)]
12pub struct Policy {
13 block_on_hazards: Hazards,
14 block_device_on_hazards: HashMap<usize, Hazards>,
15}
16
17impl Policy {
18 #[must_use]
21 #[inline]
22 pub fn new(block_on_hazards: Hazards) -> Self {
23 Self {
24 block_on_hazards,
25 block_device_on_hazards: HashMap::new(),
26 }
27 }
28
29 #[must_use]
32 #[inline]
33 pub fn only_local_policy(id: usize, hazards: Hazards) -> Self {
34 let policy = Self::init();
35 policy.block_device_on_hazards(id, hazards)
36 }
37
38 #[must_use]
41 #[inline]
42 pub fn block_device_on_hazards(mut self, id: usize, hazards: Hazards) -> Self {
43 self.block_device_on_hazards.insert(id, hazards);
44 self
45 }
46
47 pub(crate) fn init() -> Self {
48 Self {
49 block_on_hazards: Hazards::new(),
50 block_device_on_hazards: HashMap::new(),
51 }
52 }
53
54 pub(crate) fn global_blocked_hazards(&self, hazards: &Hazards) -> Hazards {
55 let mut blocked_hazards = Hazards::new();
56 for hazard in hazards {
57 if self.block_on_hazards.contains(hazard) {
58 blocked_hazards.add(*hazard);
59 }
60 }
61 blocked_hazards
62 }
63
64 pub(crate) fn local_blocked_hazards(&self, id: usize, hazards: &Hazards) -> Hazards {
65 if let Some(local_hazards) = self.block_device_on_hazards.get(&id) {
66 let mut blocked_hazards = Hazards::new();
67 for hazard in hazards {
68 if local_hazards.contains(hazard) {
69 blocked_hazards.add(*hazard);
70 }
71 }
72 blocked_hazards
73 } else {
74 Hazards::new()
75 }
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use std::collections::HashMap;
82
83 use tosca::hazards::{Hazard, Hazards};
84
85 use super::Policy;
86
87 fn create_policy() -> (Hazards, Policy) {
88 let hazards = Hazards::new().insert(Hazard::ElectricEnergyConsumption);
89
90 let policy = Policy::new(hazards.clone());
91
92 (hazards, policy)
93 }
94
95 fn check_device_policies(policy: &Policy, block_on_hazards: Hazards, local_hazards: &Hazards) {
96 let mut devices_hazards = HashMap::new();
97 devices_hazards.insert(1, local_hazards.clone());
98 devices_hazards.insert(2, local_hazards.clone());
99
100 assert_eq!(
101 policy,
102 &Policy {
103 block_on_hazards,
104 block_device_on_hazards: devices_hazards,
105 }
106 );
107 }
108
109 #[test]
110 fn only_global_policy() {
111 let (hazards, policy) = create_policy();
112
113 assert_eq!(
114 policy,
115 Policy {
116 block_on_hazards: hazards,
117 block_device_on_hazards: HashMap::new()
118 }
119 );
120 }
121
122 #[test]
123 fn only_local_policy() {
124 let local_hazards = Hazards::new().insert(Hazard::Explosion);
125
126 let policy = Policy::only_local_policy(1, local_hazards.clone())
127 .block_device_on_hazards(2, local_hazards.clone());
128
129 check_device_policies(&policy, Hazards::new(), &local_hazards);
130 }
131
132 #[test]
133 fn complete_policy() {
134 let (global_hazards, policy) = create_policy();
135
136 let local_hazards = Hazards::new().insert(Hazard::Explosion);
137
138 let policy = policy
139 .block_device_on_hazards(1, local_hazards.clone())
140 .block_device_on_hazards(2, local_hazards.clone());
141
142 check_device_policies(&policy, global_hazards, &local_hazards);
143 }
144}