fit_rust/protocol/
macros.rs

1use crate::protocol::data_field::DataField;
2use crate::protocol::value::Value;
3
4// Helper functions and macros for the merge_sessions function
5#[macro_export]
6macro_rules! update_field {
7    ($fields:expr, $field_num:expr, $value:expr) => {
8        if let Some(field) = $fields.iter_mut().find(|f| f.field_num == $field_num) {
9            field.value = $value;
10        }
11    };
12}
13
14pub fn get_field_value(field_num: u8, values: &[DataField]) -> Option<Value> {
15    values
16        .iter()
17        .find(|field| field.field_num == field_num)
18        .and_then(|field| Some(field.value.clone()))
19}
20
21#[macro_export]
22macro_rules! merge_stats {
23    // Base case
24    () => {};
25
26    // Summation case
27    (sum $field_num:expr, $total_value:expr, $session:expr, $($rest:tt)*) => {
28         if let Some(value) = get_field_value($field_num, &$session.data.values) {
29            match value {
30                Value::U32(val) => {
31                    if let Value::U32(total_value) = $total_value {
32                        $total_value = Value::U32(total_value + val);
33                    }
34                },
35                Value::U16(val) => {
36                    if let Value::U16(total_value) = $total_value {
37                        $total_value = Value::U16(total_value + val);
38                    }
39                },
40                _ => {}
41            }
42        }
43        merge_stats!($($rest)*);
44    };
45
46    // Maximum value case
47    (max $field_num:expr, $max_value:expr, $session:expr, $($rest:tt)*) => {
48         if let Some(value) = get_field_value($field_num, &$session.data.values) {
49            match value {
50                Value::Time(val) => {
51                    if let Value::Time(max_val) = $max_value {
52                        $max_value = Value::Time(max_val.max(val));
53                    }
54                },
55                Value::U16(val) => {
56                    if let Value::U16(max_val) = $max_value {
57                        $max_value = Value::U16(max_val.max(val));
58                    }
59                },
60                Value::I16(val) => {
61                    if let Value::I16(max_val) = $max_value {
62                        $max_value = Value::I16(max_val.max(val));
63                    }
64                },
65                Value::U8(val) => {
66                    if let Value::U8(max_val) = $max_value {
67                        $max_value = Value::U8(max_val.max(val));
68                    }
69                },
70                Value::I8(val) => {
71                    if let Value::I8(max_val) = $max_value {
72                        $max_value = Value::I8(max_val.max(val));
73                    }
74                },
75                _ => {}
76            }
77        }
78        merge_stats!($($rest)*);
79    };
80
81    // Minimum value case
82    (min $field_num:expr, $min_value:expr, $session:expr, $($rest:tt)*) => {
83        if let Some(value) = get_field_value($field_num, &$session.data.values) {
84            match value {
85                Value::Time(val) => {
86                    if let Value::Time(min_value) = $min_value {
87                        $min_value = Value::Time(min_value.min(val));
88                    }
89                },
90                Value::U16(val) => {
91                    if let Value::U16(min_value) = $min_value {
92                        $min_value = Value::U16(min_value.min(val));
93                    }
94                },
95                Value::U8(val) => {
96                    if let Value::U8(min_value) = $min_value {
97                        $min_value = Value::U8(min_value.min(val));
98                    }
99                },
100                _ => {}
101            }
102        }
103        merge_stats!($($rest)*);
104    };
105
106
107    // Average value case
108    (avg $field_num:expr, $total_value:expr, $count:expr, $session:expr, $($rest:tt)*) => {
109         if let Some(value) = get_field_value($field_num, &$session.data.values) {
110            match value {
111                Value::U16(val) => {
112                    if let Value::I32(total_value) = $total_value {
113                        $total_value = Value::I32(total_value + (val as i32));
114                        $count = $count + 1;
115                    }
116                },
117                Value::I16(val) => {
118                    if let Value::I32(total_value) = $total_value {
119                        $total_value = Value::I32(total_value + (val as i32));
120                        $count = $count + 1;
121                    }
122                },
123                Value::U8(val) => {
124                    if let Value::I32(total_value) = $total_value {
125                        $total_value = Value::I32(total_value + (val as i32));
126                        $count = $count + 1;
127                    }
128                },
129                Value::I8(val) => {
130                    if let Value::I32(total_value) = $total_value {
131                        $total_value = Value::I32(total_value + (val as i32));
132                        $count = $count + 1;
133                    }
134                },
135                _ => {}
136            }
137        }
138        merge_stats!($($rest)*);
139    };
140}