bnr_xfs/history/
system_failure_history.rs

1use crate::xfs::method_response::XfsMethodResponse;
2use crate::{create_xfs_array, create_xfs_struct};
3use crate::{
4    BillErrorCount, BillJamCount, BillTooLongInBottomTransportBwCount, BillTooLongInSpineFwCount,
5    BillTooShortInBottomTransportBwCount, BillTooShortInSpineFwCount, BottomTransportCount,
6    BundlerCount, ConfigurationErrorCount, EnvironmentErrorCount, Error, HardwareFailureCount,
7    HardwareFailureWithBillStoppedCount, IncompatibleSoftwareCount, InterfaceCount,
8    MissingModuleCount, ModuleCount, OperationalDegradedCount, PositionerCount,
9    RecognitionSystemCount, ResetWithCoverOpenCount, ResetWithInterlockOpenCount, Result,
10    SpineCount, TransportErrorCount, UnnamedCount,
11};
12
13const BILL_ENDING_COUNTERS_LEN: usize = 4;
14const INCIDENT_START_COUNTERS_LEN: usize = 25;
15
16const UNNAMED_COUNT_DEFAULT: UnnamedCount = UnnamedCount::new();
17
18const MODULE_COUNT_LIST_LEN: usize = 10;
19const MODULE_COUNT_DEFAULT: ModuleCount = ModuleCount::new();
20
21const INTERFACE_COUNT_LIST_LEN: usize = 10;
22const INTERFACE_COUNT_DEFAULT: InterfaceCount = InterfaceCount::new();
23
24create_xfs_struct!(
25    MainModuleSectionCounters,
26    "mainModuleSectionCounters",
27    [
28        positioner_count: PositionerCount,
29        recognition_system_count: RecognitionSystemCount,
30        bottom_transport_count: BottomTransportCount,
31        bundler_count: BundlerCount
32    ],
33    "Represents the main module section counters."
34);
35
36create_xfs_struct!(
37    IncidentStartSectionCounters,
38    "incidentStartSectionCounters",
39    [
40        positioner_count: PositionerCount,
41        recognition_system_count: RecognitionSystemCount,
42        bottom_transport_count: BottomTransportCount,
43        bundler_count: BundlerCount,
44        spine_count: SpineCount,
45        module_counts: ModuleCountList,
46        interface_counts: InterfaceCountList
47    ],
48    "Represents the incident start section counters."
49);
50
51create_xfs_array!(
52    ModuleCountList,
53    "moduleCountList",
54    ModuleCount,
55    MODULE_COUNT_LIST_LEN,
56    MODULE_COUNT_DEFAULT,
57    "Represents a list of module count items."
58);
59
60create_xfs_array!(
61    InterfaceCountList,
62    "interfaceCountList",
63    InterfaceCount,
64    INTERFACE_COUNT_LIST_LEN,
65    INTERFACE_COUNT_DEFAULT,
66    "Represents a list of interface count items."
67);
68
69create_xfs_array!(
70    BillEndingInMMSectionCounters,
71    "billEndingInMMSectionCounters",
72    UnnamedCount,
73    BILL_ENDING_COUNTERS_LEN,
74    UNNAMED_COUNT_DEFAULT,
75    "Represents a list of bill ending in main module section count items."
76);
77
78create_xfs_array!(
79    IncidentStartSectionCountersList,
80    "incidentStartSectionCounters",
81    UnnamedCount,
82    INCIDENT_START_COUNTERS_LEN,
83    UNNAMED_COUNT_DEFAULT,
84    "Represents a list of incident start section count items."
85);
86
87create_xfs_struct!(
88    PerSectionHistoryInternal,
89    "perSectionHistory",
90    [
91        bill_ending_in_mm_section_counters: BillEndingInMMSectionCounters,
92        incident_start_section: IncidentStartSectionCountersList
93    ],
94    "Represents the internal XFS representation of per-section history."
95);
96
97create_xfs_struct!(
98    PerSectionHistory,
99    "perSectionHistory",
100    [
101        bill_ending_in_mm_section_counters: MainModuleSectionCounters,
102        incident_start_section: IncidentStartSectionCounters
103    ],
104    "Represents the internal XFS representation of per-section history."
105);
106
107impl From<&BillEndingInMMSectionCounters> for MainModuleSectionCounters {
108    fn from(val: &BillEndingInMMSectionCounters) -> Self {
109        let items = val.items();
110        Self {
111            positioner_count: items
112                .first()
113                .cloned()
114                .unwrap_or(UnnamedCount::new())
115                .inner()
116                .into(),
117            recognition_system_count: items
118                .get(1)
119                .cloned()
120                .unwrap_or(UnnamedCount::new())
121                .inner()
122                .into(),
123            bottom_transport_count: items
124                .get(2)
125                .cloned()
126                .unwrap_or(UnnamedCount::new())
127                .inner()
128                .into(),
129            bundler_count: items
130                .get(3)
131                .cloned()
132                .unwrap_or(UnnamedCount::new())
133                .inner()
134                .into(),
135        }
136    }
137}
138
139impl From<BillEndingInMMSectionCounters> for MainModuleSectionCounters {
140    fn from(val: BillEndingInMMSectionCounters) -> Self {
141        (&val).into()
142    }
143}
144
145impl From<&IncidentStartSectionCountersList> for IncidentStartSectionCounters {
146    fn from(val: &IncidentStartSectionCountersList) -> Self {
147        let items = val.items();
148        Self {
149            positioner_count: items
150                .first()
151                .cloned()
152                .unwrap_or(UnnamedCount::new())
153                .inner()
154                .into(),
155            recognition_system_count: items
156                .get(1)
157                .cloned()
158                .unwrap_or(UnnamedCount::new())
159                .inner()
160                .into(),
161            bottom_transport_count: items
162                .get(2)
163                .cloned()
164                .unwrap_or(UnnamedCount::new())
165                .inner()
166                .into(),
167            bundler_count: items
168                .get(3)
169                .cloned()
170                .unwrap_or(UnnamedCount::new())
171                .inner()
172                .into(),
173            spine_count: items
174                .get(4)
175                .cloned()
176                .unwrap_or(UnnamedCount::new())
177                .inner()
178                .into(),
179            module_counts: ModuleCountList::new().with_items(
180                items
181                    .iter()
182                    .skip(5)
183                    .take(10)
184                    .map(|i| ModuleCount::from(i.inner()))
185                    .collect::<Vec<ModuleCount>>()
186                    .as_ref(),
187            ),
188            interface_counts: InterfaceCountList::new().with_items(
189                items
190                    .iter()
191                    .skip(15)
192                    .take(10)
193                    .map(|i| InterfaceCount::from(i.inner()))
194                    .collect::<Vec<InterfaceCount>>()
195                    .as_ref(),
196            ),
197        }
198    }
199}
200
201impl From<IncidentStartSectionCountersList> for IncidentStartSectionCounters {
202    fn from(val: IncidentStartSectionCountersList) -> Self {
203        (&val).into()
204    }
205}
206
207impl From<&PerSectionHistoryInternal> for PerSectionHistory {
208    fn from(val: &PerSectionHistoryInternal) -> Self {
209        Self {
210            bill_ending_in_mm_section_counters: val.bill_ending_in_mm_section_counters().into(),
211            incident_start_section: val.incident_start_section().into(),
212        }
213    }
214}
215
216impl From<PerSectionHistoryInternal> for PerSectionHistory {
217    fn from(val: PerSectionHistoryInternal) -> Self {
218        (&val).into()
219    }
220}
221
222create_xfs_struct!(
223    SystemFailureHistory,
224    "systemFailureHistory",
225    [
226        hardware_failure_count: HardwareFailureCount,
227        hardware_failure_with_bill_stopped_count: HardwareFailureWithBillStoppedCount,
228        operational_degraded_count: OperationalDegradedCount,
229        bill_jam_count: BillJamCount,
230        environment_error_count: EnvironmentErrorCount,
231        bill_error_count: BillErrorCount,
232        transport_error_count: TransportErrorCount,
233        bill_too_short_in_bottom_transport_bw_count: BillTooShortInBottomTransportBwCount,
234        bill_too_long_in_bottom_transport_bw_count: BillTooLongInBottomTransportBwCount,
235        bill_too_short_in_spine_fw_count: BillTooShortInSpineFwCount,
236        bill_too_long_in_spine_fw_count: BillTooLongInSpineFwCount,
237        missing_module_count: MissingModuleCount,
238        configuration_error_count: ConfigurationErrorCount,
239        incompatible_software_count: IncompatibleSoftwareCount,
240        reset_with_cover_open_count: ResetWithCoverOpenCount,
241        reset_with_interlock_open_count: ResetWithInterlockOpenCount,
242        per_section_history: PerSectionHistory
243    ],
244    "Represents the history of system failure events."
245);
246
247create_xfs_struct!(
248    SystemFailureHistoryInternal,
249    "systemFailureHistory",
250    [
251        hardware_failure_count: HardwareFailureCount,
252        hardware_failure_with_bill_stopped_count: HardwareFailureWithBillStoppedCount,
253        operational_degraded_count: OperationalDegradedCount,
254        bill_jam_count: BillJamCount,
255        environment_error_count: EnvironmentErrorCount,
256        bill_error_count: BillErrorCount,
257        transport_error_count: TransportErrorCount,
258        bill_too_short_in_bottom_transport_bw_count: BillTooShortInBottomTransportBwCount,
259        bill_too_long_in_bottom_transport_bw_count: BillTooLongInBottomTransportBwCount,
260        bill_too_short_in_spine_fw_count: BillTooShortInSpineFwCount,
261        bill_too_long_in_spine_fw_count: BillTooLongInSpineFwCount,
262        missing_module_count: MissingModuleCount,
263        configuration_error_count: ConfigurationErrorCount,
264        incompatible_software_count: IncompatibleSoftwareCount,
265        reset_with_cover_open_count: ResetWithCoverOpenCount,
266        reset_with_interlock_open_count: ResetWithInterlockOpenCount,
267        per_section_history: PerSectionHistoryInternal
268    ],
269    "Alternative internal representation the history of system failure events."
270);
271
272impl From<&SystemFailureHistoryInternal> for SystemFailureHistory {
273    fn from(val: &SystemFailureHistoryInternal) -> Self {
274        Self {
275            hardware_failure_count: val.hardware_failure_count,
276            hardware_failure_with_bill_stopped_count: val.hardware_failure_with_bill_stopped_count,
277            operational_degraded_count: val.operational_degraded_count,
278            bill_jam_count: val.bill_jam_count,
279            environment_error_count: val.environment_error_count,
280            bill_error_count: val.bill_error_count,
281            transport_error_count: val.transport_error_count,
282            bill_too_short_in_bottom_transport_bw_count: val
283                .bill_too_short_in_bottom_transport_bw_count,
284            bill_too_long_in_bottom_transport_bw_count: val
285                .bill_too_long_in_bottom_transport_bw_count,
286            bill_too_short_in_spine_fw_count: val.bill_too_short_in_spine_fw_count,
287            bill_too_long_in_spine_fw_count: val.bill_too_long_in_spine_fw_count,
288            missing_module_count: val.missing_module_count,
289            configuration_error_count: val.configuration_error_count,
290            incompatible_software_count: val.incompatible_software_count,
291            reset_with_cover_open_count: val.reset_with_cover_open_count,
292            reset_with_interlock_open_count: val.reset_with_interlock_open_count,
293            per_section_history: val.per_section_history().into(),
294        }
295    }
296}
297
298impl From<SystemFailureHistoryInternal> for SystemFailureHistory {
299    fn from(val: SystemFailureHistoryInternal) -> Self {
300        (&val).into()
301    }
302}
303
304impl TryFrom<&XfsMethodResponse> for SystemFailureHistory {
305    type Error = Error;
306
307    fn try_from(val: &XfsMethodResponse) -> Result<Self> {
308        let xfs_struct = val
309            .as_params()?
310            .params()
311            .iter()
312            .map(|m| m.inner())
313            .find(|m| m.value().xfs_struct().is_some())
314            .ok_or(Error::Xfs(format!(
315                "Expected SystemFailureHistory XfsMethodResponse, have: {val}"
316            )))?
317            .value();
318
319        match SystemFailureHistory::try_from(xfs_struct) {
320            Ok(ret) => Ok(ret),
321            Err(err) => {
322                log::warn!("Error parsing SystemFailureHistory: {err}");
323                log::debug!("Trying SystemFailureHistoryInternal representation");
324
325                Ok(SystemFailureHistoryInternal::try_from(xfs_struct)?.into())
326            }
327        }
328    }
329}
330
331impl TryFrom<XfsMethodResponse> for SystemFailureHistory {
332    type Error = Error;
333
334    fn try_from(val: XfsMethodResponse) -> Result<Self> {
335        (&val).try_into()
336    }
337}