1#[macro_use]
4mod trace_field;
5
6pub(crate) mod gps;
7pub(crate) mod gps_home;
8pub(crate) mod main;
9pub(crate) mod slow;
10
11use alloc::borrow::ToOwned as _;
12use alloc::format;
13use alloc::vec::Vec;
14use core::fmt;
15use core::iter::{FusedIterator, Peekable};
16use core::marker::PhantomData;
17
18pub use self::gps::{GpsFrame, GpsFrameDef, GpsUnit, GpsValue};
19pub(crate) use self::gps_home::{GpsHomeFrame, GpsPosition};
20pub use self::main::{MainFrame, MainFrameDef, MainUnit, MainValue};
21pub use self::slow::{SlowFrame, SlowFrameDef, SlowUnit, SlowValue};
22use crate::filter::AppliedFilter;
23use crate::headers::{ParseError, ParseResult};
24use crate::parser::{Encoding, InternalResult};
25use crate::predictor::{Predictor, PredictorContext};
26use crate::units::prelude::*;
27use crate::{units, Reader};
28
29mod seal {
30 pub trait Sealed {}
31}
32
33pub trait FrameDef<'data>: seal::Sealed {
38 type Unit: Into<Unit>;
39
40 fn len(&self) -> usize;
42
43 fn is_empty(&self) -> bool {
46 self.len() == 0
47 }
48
49 fn get<'def>(&'def self, index: usize) -> Option<FieldDef<'data, Self::Unit>>
51 where
52 'data: 'def;
53
54 fn iter<'def>(&'def self) -> FieldDefIter<'data, 'def, Self>
56 where
57 Self: Sized,
58 {
59 FieldDefIter {
60 frame: self,
61 next: 0,
62 _data: &PhantomData,
63 }
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Hash)]
69pub struct FieldDef<'data, U> {
70 pub name: &'data str,
71 pub unit: U,
72 pub signed: bool,
73}
74
75#[derive(Debug)]
76pub struct FieldDefIter<'data, 'def, F> {
77 frame: &'def F,
78 next: usize,
79 _data: &'data PhantomData<()>,
80}
81
82impl<'data, F: FrameDef<'data>> Iterator for FieldDefIter<'data, '_, F> {
83 type Item = FieldDef<'data, F::Unit>;
84
85 fn next(&mut self) -> Option<Self::Item> {
86 let value = self.frame.get(self.next)?;
87 self.next += 1;
88 Some(value)
89 }
90}
91
92impl<'data, F: FrameDef<'data>> FusedIterator for FieldDefIter<'data, '_, F> {}
93
94pub trait Frame: seal::Sealed {
99 type Value: Into<Value>;
100
101 fn len(&self) -> usize;
103
104 fn is_empty(&self) -> bool {
107 self.len() == 0
108 }
109
110 fn get_raw(&self, index: usize) -> Option<u32>;
119
120 fn iter_raw(&self) -> RawFieldIter<'_, Self>
122 where
123 Self: Sized,
124 {
125 RawFieldIter {
126 frame: self,
127 next: 0,
128 }
129 }
130
131 fn get(&self, index: usize) -> Option<Self::Value>;
133
134 fn iter(&self) -> FieldIter<'_, Self>
136 where
137 Self: Sized,
138 {
139 FieldIter {
140 frame: self,
141 next: 0,
142 }
143 }
144}
145
146#[derive(Debug)]
149pub struct RawFieldIter<'f, F> {
150 frame: &'f F,
151 next: usize,
152}
153
154impl<F: Frame> Iterator for RawFieldIter<'_, F> {
155 type Item = u32;
156
157 fn next(&mut self) -> Option<Self::Item> {
158 let value = self.frame.get_raw(self.next)?;
159 self.next += 1;
160 Some(value)
161 }
162}
163
164impl<F: Frame> FusedIterator for RawFieldIter<'_, F> {}
165
166#[derive(Debug)]
169pub struct FieldIter<'f, F> {
170 frame: &'f F,
171 next: usize,
172}
173
174impl<F: Frame> Iterator for FieldIter<'_, F> {
175 type Item = F::Value;
176
177 fn next(&mut self) -> Option<Self::Item> {
178 let value = self.frame.get(self.next)?;
179 self.next += 1;
180 Some(value)
181 }
182}
183
184impl<F: Frame> FusedIterator for FieldIter<'_, F> {}
185
186#[derive(Debug)]
189pub struct FilteredFrameDef<'a, F> {
190 def: &'a F,
191 filter: &'a AppliedFilter,
192}
193
194impl<'a, F> FilteredFrameDef<'a, F> {
195 pub(super) fn new(def: &'a F, filter: &'a AppliedFilter) -> Self {
196 Self { def, filter }
197 }
198}
199
200impl<F: seal::Sealed> seal::Sealed for FilteredFrameDef<'_, F> {}
201
202impl<'data, F: FrameDef<'data>> FrameDef<'data> for FilteredFrameDef<'_, F> {
203 type Unit = F::Unit;
204
205 #[inline]
206 fn len(&self) -> usize {
207 self.filter.len()
208 }
209
210 fn get<'def>(&'def self, index: usize) -> Option<FieldDef<'data, Self::Unit>>
211 where
212 'data: 'def,
213 {
214 let index = self.filter.get(index)?;
215 self.def.get(index)
216 }
217}
218
219#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
220#[repr(u8)]
221pub enum FrameKind {
222 Event,
223 Data(DataFrameKind),
224}
225
226impl FrameKind {
227 pub(crate) const fn from_byte(byte: u8) -> Option<Self> {
228 match byte {
229 b'E' => Some(Self::Event),
230 _ => {
231 if let Some(kind) = DataFrameKind::from_byte(byte) {
232 Some(Self::Data(kind))
233 } else {
234 None
235 }
236 }
237 }
238 }
239}
240
241impl From<FrameKind> for char {
242 fn from(kind: FrameKind) -> Self {
243 match kind {
244 FrameKind::Event => 'E',
245 FrameKind::Data(kind) => kind.into(),
246 }
247 }
248}
249
250impl From<FrameKind> for u8 {
251 fn from(kind: FrameKind) -> Self {
252 match kind {
253 FrameKind::Event => b'E',
254 FrameKind::Data(kind) => kind.into(),
255 }
256 }
257}
258
259impl fmt::Display for FrameKind {
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 match self {
262 Self::Event => f.write_str("event"),
263 Self::Data(kind) => kind.fmt(f),
264 }
265 }
266}
267
268byte_enum! {
269 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
270 #[cfg_attr(feature = "_serde", derive(serde::Serialize))]
271 #[repr(u8)]
272 pub enum DataFrameKind {
273 Intra = b'I',
274 Inter = b'P',
275 Gps = b'G',
276 GpsHome = b'H',
277 Slow = b'S',
278 }
279}
280
281impl DataFrameKind {
282 pub(crate) fn from_letter(s: &str) -> Option<Self> {
283 match s {
284 "G" => Some(Self::Gps),
285 "H" => Some(Self::GpsHome),
286 "I" => Some(Self::Intra),
287 "P" => Some(Self::Inter),
288 "S" => Some(Self::Slow),
289 _ => None,
290 }
291 }
292}
293
294impl From<DataFrameKind> for char {
295 fn from(kind: DataFrameKind) -> Self {
296 match kind {
297 DataFrameKind::Gps => 'G',
298 DataFrameKind::GpsHome => 'H',
299 DataFrameKind::Intra => 'I',
300 DataFrameKind::Inter => 'P',
301 DataFrameKind::Slow => 'S',
302 }
303 }
304}
305
306impl fmt::Display for DataFrameKind {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 let kind = match self {
309 Self::Intra => "intra",
310 Self::Inter => "inter",
311 Self::Gps => "GPS",
312 Self::GpsHome => "GPS home",
313 Self::Slow => "slow",
314 };
315
316 f.write_str(kind)
317 }
318}
319
320trait FieldDefDetails<'data> {
321 fn name(&self) -> &'data str;
322 fn predictor(&self) -> Predictor;
323 fn encoding(&self) -> Encoding;
324 fn signed(&self) -> bool;
325}
326
327#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
328#[cfg_attr(feature = "_serde", derive(serde::Serialize))]
329pub enum Unit {
330 Amperage,
331 Voltage,
332 Acceleration,
333 Rotation,
334 FlightMode,
335 State,
336 FailsafePhase,
337 GpsCoordinate,
338 Altitude,
339 Velocity,
340 GpsHeading,
341 Boolean,
342 Unitless,
343}
344
345#[derive(Debug, Clone, Copy, PartialEq)]
346pub enum Value {
347 Amperage(ElectricCurrent),
348 Voltage(ElectricPotential),
349 Acceleration(Acceleration),
350 Rotation(AngularVelocity),
351 FlightMode(units::FlightModeSet),
352 State(units::StateSet),
353 FailsafePhase(units::FailsafePhase),
354 Boolean(bool),
355 GpsCoordinate(f64),
356 Altitude(Length),
357 Velocity(Velocity),
358 GpsHeading(f64),
359 Unsigned(u32),
360 Signed(i32),
361}
362
363pub(crate) fn is_frame_def_header(header: &str) -> bool {
364 parse_frame_def_header(header).is_some()
365}
366
367pub(crate) fn parse_frame_def_header(header: &str) -> Option<(DataFrameKind, DataFrameProperty)> {
368 let header = header.strip_prefix("Field ")?;
369 let (kind, property) = header.split_once(' ')?;
370
371 Some((
372 DataFrameKind::from_letter(kind)?,
373 DataFrameProperty::from_name(property)?,
374 ))
375}
376
377#[derive(Debug, Clone, Copy, PartialEq, Eq)]
379pub(crate) enum DataFrameProperty {
380 Name,
381 Predictor,
382 Encoding,
383 Signed,
384}
385
386impl DataFrameProperty {
387 pub(crate) fn from_name(s: &str) -> Option<Self> {
388 match s {
389 "name" => Some(Self::Name),
390 "predictor" => Some(Self::Predictor),
391 "encoding" => Some(Self::Encoding),
392 "signed" => Some(Self::Signed),
393 _ => None,
394 }
395 }
396}
397
398fn missing_header_error(kind: DataFrameKind, property: &'static str) -> ParseError {
399 tracing::error!("missing header `Field {} {property}`", char::from(kind));
400 ParseError::MissingHeader
401}
402
403fn parse_names(
404 kind: DataFrameKind,
405 names: Option<&str>,
406) -> ParseResult<impl Iterator<Item = &'_ str>> {
407 let names = names.ok_or_else(|| missing_header_error(kind, "name"))?;
408 Ok(names.split(','))
409}
410
411fn parse_enum_list<'a, T>(
412 kind: DataFrameKind,
413 property: &'static str,
414 s: Option<&'a str>,
415 parse: impl Fn(&str) -> Option<T> + 'a,
416) -> ParseResult<impl Iterator<Item = ParseResult<T>> + 'a> {
417 let s = s.ok_or_else(|| missing_header_error(kind, property))?;
418 Ok(s.split(',').map(move |s| {
419 parse(s).ok_or_else(|| ParseError::InvalidHeader {
420 header: format!("Field {} {property}", char::from(kind)),
421 value: s.to_owned(),
422 })
423 }))
424}
425
426#[inline]
427fn parse_predictors(
428 kind: DataFrameKind,
429 predictors: Option<&'_ str>,
430) -> ParseResult<impl Iterator<Item = ParseResult<Predictor>> + '_> {
431 parse_enum_list(kind, "predictor", predictors, Predictor::from_num_str)
432}
433
434#[inline]
435fn parse_encodings(
436 kind: DataFrameKind,
437 encodings: Option<&'_ str>,
438) -> ParseResult<impl Iterator<Item = ParseResult<Encoding>> + '_> {
439 parse_enum_list(kind, "encoding", encodings, Encoding::from_num_str)
440}
441
442fn parse_signs(
443 kind: DataFrameKind,
444 names: Option<&str>,
445) -> ParseResult<impl Iterator<Item = bool> + '_> {
446 let names = names.ok_or_else(|| missing_header_error(kind, "signed"))?;
447 Ok(names.split(',').map(|s| s.trim() != "0"))
448}
449
450fn count_fields_with_same_encoding(
451 fields: &mut Peekable<impl Iterator<Item = Encoding>>,
452 max: usize,
453 encoding: Encoding,
454) -> usize {
455 let mut extra = 0;
456 while extra < max && fields.next_if_eq(&encoding).is_some() {
457 extra += 1;
458 }
459 extra
460}
461
462fn read_field_values<T>(
463 data: &mut Reader,
464 fields: &[T],
465 get_encoding: impl Fn(&T) -> Encoding,
466) -> InternalResult<Vec<u32>> {
467 let mut encodings = fields.iter().map(get_encoding).peekable();
468 let mut values = Vec::with_capacity(encodings.len());
469
470 while let Some(encoding) = encodings.next() {
471 let extra = encoding.max_chunk_size() - 1;
472 let extra = count_fields_with_same_encoding(&mut encodings, extra, encoding);
473
474 encoding.decode_into(data, extra, &mut values)?;
475 }
476
477 debug_assert_eq!(values.len(), fields.len());
478
479 Ok(values)
480}
481
482fn parse_impl<'data, F: FieldDefDetails<'data>>(
483 mut ctx: PredictorContext<'_, 'data>,
484 raw: &[u32],
485 fields: impl IntoIterator<Item = F>,
486 update_ctx: impl Fn(&mut PredictorContext<'_, 'data>, usize),
487) -> Vec<u32> {
488 let mut values = Vec::with_capacity(raw.len());
489
490 for (i, field) in fields.into_iter().enumerate() {
491 let encoding = field.encoding();
492 let predictor = field.predictor();
493
494 let raw = raw[i];
495 let signed = encoding.is_signed();
496
497 update_ctx(&mut ctx, i);
498
499 trace_field!(pre, field = field, enc = encoding, raw = raw);
500
501 let value = predictor.apply(raw, signed, Some(&values), &ctx);
502 values.push(value);
503
504 trace_field!(
505 post,
506 field = field,
507 pred = predictor,
508 final = value
509 );
510 }
511
512 values
513}