gnss_qc_traits/processing/
decim.rs1use crate::processing::{FilterItem, ItemError};
2use hifitime::Duration;
3use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum Error {
8 #[error("invalid decimated item")]
9 InvalidDecimItem(#[from] ItemError),
10 #[error("failed to parse decimation attribute \"{0}\"")]
11 AttributeParsingError(String),
12}
13
14#[derive(Clone, Debug, PartialEq)]
16pub enum DecimationFilterType {
17 Modulo(u32),
19 Duration(Duration),
21}
22
23#[derive(Clone, Debug, PartialEq)]
24pub struct DecimationFilter {
25 pub filter: DecimationFilterType,
27 pub item: Option<FilterItem>,
31}
32
33impl DecimationFilter {
34 pub fn duration(dt: Duration) -> Self {
36 Self {
37 item: None,
38 filter: DecimationFilterType::Duration(dt),
39 }
40 }
41 pub fn modulo(modulo: u32) -> Self {
43 Self {
44 item: None,
45 filter: DecimationFilterType::Modulo(modulo),
46 }
47 }
48 pub fn with_item(&self, item: FilterItem) -> Self {
50 let mut s = self.clone();
51 s.item = Some(item.clone());
52 s
53 }
54}
55
56pub trait Decimate {
58 fn decimate(&self, f: &DecimationFilter) -> Self;
60 fn decimate_mut(&mut self, f: &DecimationFilter);
62}
63
64impl std::str::FromStr for DecimationFilter {
65 type Err = Error;
66 fn from_str(content: &str) -> Result<Self, Self::Err> {
67 let items: Vec<&str> = content.trim().split(':').collect();
68 if let Ok(dt) = Duration::from_str(items[0].trim()) {
69 Ok(Self {
70 item: {
71 if items.len() > 1 {
72 let item = FilterItem::from_str(items[1].trim())?;
73 Some(item)
74 } else {
75 None }
77 },
78 filter: DecimationFilterType::Duration(dt),
79 })
80 } else if let Ok(r) = items[0].trim().parse::<u32>() {
81 Ok(Self {
82 item: {
83 if items.len() > 1 {
84 let item = FilterItem::from_str(items[1].trim())?;
85 Some(item)
86 } else {
87 None
88 }
89 },
90 filter: DecimationFilterType::Modulo(r),
91 })
92 } else {
93 Err(Error::AttributeParsingError(items[0].to_string()))
94 }
95 }
96}