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