mod bus_frame;
mod bus_logger_config;
mod bus_logger_stats;
mod timestamped_frame;
pub use bus_frame::BusFrame;
pub use bus_logger_config::BusLoggerConfig;
pub use bus_logger_stats::BusLoggerStats;
pub use timestamped_frame::TimestampedFrame;
use alloc::string::String;
use alloc::vec::Vec;
use crate::writer::MdfWrite;
use crate::{DataType, DecodedValue, MdfWriter, Result};
pub const MICROS_TO_SECONDS: f64 = 1.0 / 1_000_000.0;
#[inline]
pub fn timestamp_to_seconds(timestamp_us: u64) -> f64 {
timestamp_us as f64 * MICROS_TO_SECONDS
}
pub fn init_bus_channel_group<W: MdfWrite>(
writer: &mut MdfWriter<W>,
config: &BusLoggerConfig,
) -> Result<(String, String)> {
let cg = writer.add_channel_group(None, |_| {})?;
writer.set_channel_group_name(&cg, &config.group_name)?;
writer.set_channel_group_source(&cg, &config.source_block, Some(&config.source_name))?;
let time_ch = writer.add_channel(&cg, None, |ch| {
ch.data_type = DataType::FloatLE;
ch.name = Some(String::from("Timestamp"));
ch.bit_count = 64;
})?;
writer.set_time_channel(&time_ch)?;
writer.set_channel_unit(&time_ch, "s")?;
let data_ch = writer.add_channel(&cg, Some(&time_ch), |ch| {
ch.data_type = DataType::ByteArray;
ch.name = Some(config.data_channel_name.clone());
ch.bit_count = config.data_channel_bits;
})?;
Ok((cg, data_ch))
}
pub fn write_timestamped_frames<W, F, I>(
writer: &mut MdfWriter<W>,
channel_group: &str,
frames: I,
) -> Result<()>
where
W: MdfWrite,
F: BusFrame,
I: Iterator<Item = TimestampedFrame<F>>,
{
let frames: Vec<_> = frames.collect();
if frames.is_empty() {
return Ok(());
}
writer.start_data_block_for_cg(channel_group, 0)?;
for entry in &frames {
let values = [
DecodedValue::Float(entry.timestamp_s),
DecodedValue::ByteArray(entry.frame.to_mdf_bytes()),
];
writer.write_record(channel_group, &values)?;
}
writer.finish_data_block(channel_group)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_timestamp_conversion() {
assert_eq!(timestamp_to_seconds(0), 0.0);
assert_eq!(timestamp_to_seconds(1_000_000), 1.0);
assert_eq!(timestamp_to_seconds(500_000), 0.5);
assert_eq!(timestamp_to_seconds(1_500_000), 1.5);
}
#[test]
fn test_timestamped_frame() {
let frame = TimestampedFrame::new(2_500_000u64, vec![1u8, 2, 3]);
assert_eq!(frame.timestamp_s, 2.5);
assert_eq!(frame.frame, vec![1, 2, 3]);
}
}