tekhsi_rs 0.1.1

High-performance client for Tektronix TekHSI enabled oscilloscopes
Documentation
use smol_str::SmolStr;
use std::collections::HashMap;
use std::sync::{Arc, OnceLock};
use std::time::Duration;

use crate::data::ChannelData;

/// Acquisition of a single acquisition batch across all requested symbols.
#[derive(Debug, Clone)]
pub struct Acquisition {
    /// Channel data entries (one per subscribed symbol).
    /// Uses `Arc` for efficient sharing across multiple broadcast receivers.
    pub data: Arc<Vec<ChannelData>>,
    /// Time spent waiting for data access from the scope.
    pub wait_time: Duration,
    /// Time spent downloading waveform data.
    pub download_time: Duration,
    /// Internal lookup cache for symbol-to-index mapping.
    by_symbol: Arc<OnceLock<HashMap<SmolStr, usize>>>,
}

impl Acquisition {
    /// Build a acquisition from decoded channel data.
    ///
    /// ```rust
    /// use std::time::Duration;
    /// use tekhsi_rs::data::{ChannelData, Acquisition};
    /// use tekhsi_rs::errors::AcquisitionError;
    /// use smol_str::SmolStr;
    ///
    /// let data = vec![ChannelData::AcquisitionError {
    ///     symbol: SmolStr::new("ch1"),
    ///     error: AcquisitionError::DownloadFailed { message: "test".into() },
    /// }];
    /// let acquisition = Acquisition::new(data, Duration::from_millis(1), Duration::from_millis(2));
    /// assert!(acquisition.get_by_symbol("ch1").is_some());
    /// ```
    pub fn new(data: Vec<ChannelData>, wait_time: Duration, download_time: Duration) -> Self {
        Self {
            data: Arc::new(data),
            wait_time,
            download_time,
            by_symbol: Arc::new(OnceLock::new()),
        }
    }

    /// Look up channel data by symbol name.
    pub fn get_by_symbol(&self, symbol: &str) -> Option<&ChannelData> {
        let map = self.by_symbol.get_or_init(|| {
            self.data
                .iter()
                .enumerate()
                .map(|(idx, channel)| (channel.symbol().clone(), idx))
                .collect()
        });

        map.get(symbol).and_then(|&idx| self.data.get(idx))
    }
}