Skip to main content

mdf4_rs/channel/
channel_values_iter.rs

1//! [`ChannelValuesIter`].
2
3#[allow(unused_imports)]
4use super::*;
5use crate::{
6    Result,
7    blocks::ChannelBlock,
8    parsing::decoder::{DecodedValue, decode_channel_value_with_validity},
9};
10
11/// Streaming iterator over decoded channel values.
12///
13/// Created by [`Channel::iter_values()`]. This iterator decodes values on-demand
14/// without loading all data into memory, making it suitable for large MDF4 files.
15pub struct ChannelValuesIter<'a> {
16    pub(crate) records_iter: Box<dyn Iterator<Item = Result<&'a [u8]>> + 'a>,
17    pub(crate) block: &'a ChannelBlock,
18    pub(crate) mmap: &'a [u8],
19    pub(crate) record_id_size: usize,
20    pub(crate) cg_data_bytes: u32,
21}
22impl<'a> Iterator for ChannelValuesIter<'a> {
23    type Item = Result<Option<DecodedValue>>;
24
25    fn next(&mut self) -> Option<Self::Item> {
26        let rec_result = self.records_iter.next()?;
27
28        Some(match rec_result {
29            Ok(rec) => {
30                // Decode with validity checking
31                if let Some(decoded) = decode_channel_value_with_validity(
32                    rec,
33                    self.record_id_size,
34                    self.cg_data_bytes,
35                    self.block,
36                ) {
37                    if decoded.is_valid {
38                        // Value is valid, apply conversion
39                        match self.block.apply_conversion_value(decoded.value, self.mmap) {
40                            Ok(phys) => Ok(Some(phys)),
41                            Err(e) => Err(e),
42                        }
43                    } else {
44                        // Value is invalid according to invalidation bit
45                        Ok(None)
46                    }
47                } else {
48                    // Decoding failed
49                    Ok(None)
50                }
51            }
52            Err(e) => Err(e),
53        })
54    }
55}