blackbox_log/frame/slow/
mod.rs

1mod def;
2
3use alloc::vec::Vec;
4
5pub use self::def::*;
6use super::Unit;
7use crate::filter::AppliedFilter;
8use crate::utils::as_i32;
9use crate::{units, Headers};
10
11/// Data parsed from a slow frame.
12///
13/// Slow frames do not include any metadata. If that is desired, use the prior
14/// [`MainFrame`][super::MainFrame].
15#[derive(Debug, Clone)]
16pub struct SlowFrame<'data, 'headers, 'parser> {
17    headers: &'headers Headers<'data>,
18    raw: RawSlowFrame,
19    filter: &'parser AppliedFilter,
20}
21
22impl super::seal::Sealed for SlowFrame<'_, '_, '_> {}
23
24impl super::Frame for SlowFrame<'_, '_, '_> {
25    type Value = SlowValue;
26
27    #[inline]
28    fn len(&self) -> usize {
29        self.filter.len()
30    }
31
32    fn get_raw(&self, index: usize) -> Option<u32> {
33        let index = self.filter.get(index)?;
34        Some(self.raw.0[index])
35    }
36
37    fn get(&self, index: usize) -> Option<Self::Value> {
38        let frame_def = self.headers.slow_frame_def();
39        let index = self.filter.get(index)?;
40
41        let def = &frame_def.fields[index];
42        let raw = self.raw.0[index];
43
44        let firmware = self.headers.internal_firmware;
45        let value = match def.unit {
46            SlowUnit::FlightMode => SlowValue::FlightMode(units::FlightModeSet::new(raw, firmware)),
47            SlowUnit::State => SlowValue::State(units::StateSet::new(raw, firmware)),
48            SlowUnit::FailsafePhase => {
49                SlowValue::FailsafePhase(units::FailsafePhase::new(raw, firmware))
50            }
51            SlowUnit::Boolean => {
52                if raw > 1 {
53                    tracing::debug!("invalid boolean ({raw:0>#8x})");
54                }
55
56                SlowValue::Boolean(raw != 0)
57            }
58            SlowUnit::Unitless => SlowValue::new_unitless(raw, def.signed),
59        };
60
61        Some(value)
62    }
63}
64
65impl<'data, 'headers, 'parser> SlowFrame<'data, 'headers, 'parser> {
66    pub(crate) fn new(
67        headers: &'headers Headers<'data>,
68        raw: RawSlowFrame,
69        filter: &'parser AppliedFilter,
70    ) -> Self {
71        Self {
72            headers,
73            raw,
74            filter,
75        }
76    }
77}
78
79#[derive(Debug, Clone)]
80pub(crate) struct RawSlowFrame(Vec<u32>);
81
82impl RawSlowFrame {}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
85pub enum SlowValue {
86    FlightMode(units::FlightModeSet),
87    State(units::StateSet),
88    FailsafePhase(units::FailsafePhase),
89    Boolean(bool),
90    Unsigned(u32),
91    Signed(i32),
92}
93
94impl SlowValue {
95    const fn new_unitless(value: u32, signed: bool) -> Self {
96        if signed {
97            Self::Signed(as_i32(value))
98        } else {
99            Self::Unsigned(value)
100        }
101    }
102}
103
104impl From<SlowValue> for super::Value {
105    fn from(value: SlowValue) -> Self {
106        match value {
107            SlowValue::FlightMode(m) => Self::FlightMode(m),
108            SlowValue::State(s) => Self::State(s),
109            SlowValue::FailsafePhase(p) => Self::FailsafePhase(p),
110            SlowValue::Boolean(b) => Self::Boolean(b),
111            SlowValue::Unsigned(x) => Self::Unsigned(x),
112            SlowValue::Signed(x) => Self::Signed(x),
113        }
114    }
115}
116
117#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
118pub enum SlowUnit {
119    FlightMode,
120    State,
121    FailsafePhase,
122    Boolean,
123    Unitless,
124}
125
126impl From<SlowUnit> for Unit {
127    fn from(unit: SlowUnit) -> Self {
128        match unit {
129            SlowUnit::FlightMode => Self::FlightMode,
130            SlowUnit::State => Self::State,
131            SlowUnit::FailsafePhase => Self::FailsafePhase,
132            SlowUnit::Boolean => Self::Boolean,
133            SlowUnit::Unitless => Self::Unitless,
134        }
135    }
136}