blackbox_log/
filter.rs

1use alloc::borrow::ToOwned as _;
2use alloc::string::String;
3use alloc::vec::Vec;
4
5use hashbrown::HashSet;
6
7use crate::frame::FrameDef;
8use crate::utils::to_base_field;
9
10/// A complete set of filters ready to be passed to
11/// [`Headers::data_parser_with_filters`][crate::Headers::data_parser_with_filters].
12#[derive(Debug, Default, Clone)]
13pub struct FilterSet {
14    pub main: Filter,
15    pub slow: Filter,
16    pub gps: Filter,
17}
18
19/// A filter for the fields to include in one kind of frame.
20#[derive(Debug, Clone, Default)]
21pub enum Filter {
22    /// Include all fields of this frame kind.
23    #[default]
24    Unfiltered,
25    /// Include a subset of fields from this frame kind.
26    ///
27    /// **Note**: Any fields requested that are not present in the log will not
28    /// be included.
29    OnlyFields(FieldFilter),
30}
31
32/// A set of field names to include in one kind of frame.
33#[derive(Debug, Clone)]
34pub struct FieldFilter(HashSet<String>);
35
36impl Filter {
37    /// Only include any required fields (ie time for main and gps frames and
38    /// none for slow frames).
39    pub fn only_required() -> Self {
40        Self::OnlyFields(FieldFilter(HashSet::new()))
41    }
42
43    pub(crate) fn apply<'data, F: FrameDef<'data>>(&self, frame: &F) -> AppliedFilter {
44        match self {
45            Filter::Unfiltered => AppliedFilter::new_unfiltered(frame.len()),
46            Filter::OnlyFields(fields) => frame
47                .iter()
48                .enumerate()
49                .filter_map(|(i, field)| fields.0.contains(field.name).then_some(i))
50                .collect(),
51        }
52    }
53}
54
55impl<'a, S> From<&'a [S]> for FieldFilter
56where
57    &'a S: AsRef<str>,
58{
59    fn from(slice: &'a [S]) -> Self {
60        slice.iter().collect()
61    }
62}
63
64impl<S, const N: usize> From<[S; N]> for FieldFilter
65where
66    S: AsRef<str>,
67{
68    fn from(arr: [S; N]) -> Self {
69        arr.into_iter().collect()
70    }
71}
72
73impl<S> FromIterator<S> for FieldFilter
74where
75    S: AsRef<str>,
76{
77    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
78        let set = iter
79            .into_iter()
80            .map(|s| to_base_field(s.as_ref()).to_owned())
81            .collect();
82        Self(set)
83    }
84}
85
86#[derive(Debug, Clone, Default)]
87pub(crate) struct AppliedFilter(Vec<usize>);
88
89impl AppliedFilter {
90    fn new_unfiltered(len: usize) -> Self {
91        Self((0..len).collect())
92    }
93
94    pub(crate) fn len(&self) -> usize {
95        self.0.len()
96    }
97
98    pub(crate) fn get(&self, index: usize) -> Option<usize> {
99        self.0.get(index).copied()
100    }
101}
102
103impl<T> FromIterator<T> for AppliedFilter
104where
105    Vec<usize>: FromIterator<T>,
106{
107    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
108        Self(Vec::from_iter(iter))
109    }
110}