#![allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum TriggerMode {
Auto,
Normal,
Single,
}
#[derive(Debug, Clone)]
pub struct OscilloscopeView {
pub trigger_mode: TriggerMode,
pub trigger_level: f32,
pub time_div: f32,
pub volt_div: f32,
pub waveform: Vec<f32>,
pub enabled: bool,
}
impl OscilloscopeView {
pub fn new(buffer_size: usize) -> Self {
OscilloscopeView {
trigger_mode: TriggerMode::Auto,
trigger_level: 0.0,
time_div: 1.0,
volt_div: 1.0,
waveform: vec![0.0; buffer_size],
enabled: true,
}
}
}
pub fn new_oscilloscope_view(buffer_size: usize) -> OscilloscopeView {
OscilloscopeView::new(buffer_size)
}
pub fn osv_push_sample(osv: &mut OscilloscopeView, sample: f32) {
let n = osv.waveform.len();
if n == 0 {
return;
}
osv.waveform.rotate_left(1);
osv.waveform[n - 1] = sample;
}
pub fn osv_peak(osv: &OscilloscopeView) -> f32 {
osv.waveform
.iter()
.cloned()
.fold(0.0_f32, |a, b| a.max(b.abs()))
}
pub fn osv_set_trigger(osv: &mut OscilloscopeView, mode: TriggerMode) {
osv.trigger_mode = mode;
}
pub fn osv_set_time_div(osv: &mut OscilloscopeView, div: f32) {
osv.time_div = div.max(1e-6);
}
pub fn osv_set_enabled(osv: &mut OscilloscopeView, enabled: bool) {
osv.enabled = enabled;
}
pub fn osv_to_json(osv: &OscilloscopeView) -> String {
let trig = match osv.trigger_mode {
TriggerMode::Auto => "auto",
TriggerMode::Normal => "normal",
TriggerMode::Single => "single",
};
format!(
r#"{{"trigger":"{}","buffer_size":{},"time_div":{},"enabled":{}}}"#,
trig,
osv.waveform.len(),
osv.time_div,
osv.enabled
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_initial_waveform_zero() {
let o = new_oscilloscope_view(64);
assert!(o.waveform.iter().all(|&v| v.abs() < 1e-6), );
}
#[test]
fn test_push_sample() {
let mut o = new_oscilloscope_view(4);
osv_push_sample(&mut o, 1.0);
assert!((o.waveform[3] - 1.0).abs() < 1e-5, );
}
#[test]
fn test_peak_after_push() {
let mut o = new_oscilloscope_view(4);
osv_push_sample(&mut o, 0.7);
assert!((osv_peak(&o) - 0.7).abs() < 1e-5, );
}
#[test]
fn test_peak_initial_zero() {
let o = new_oscilloscope_view(8);
assert!((osv_peak(&o)).abs() < 1e-6, );
}
#[test]
fn test_set_trigger() {
let mut o = new_oscilloscope_view(8);
osv_set_trigger(&mut o, TriggerMode::Normal);
assert_eq!(
o.trigger_mode,
TriggerMode::Normal,
);
}
#[test]
fn test_set_time_div() {
let mut o = new_oscilloscope_view(8);
osv_set_time_div(&mut o, 2.0);
assert!((o.time_div - 2.0).abs() < 1e-5, );
}
#[test]
fn test_time_div_clamped() {
let mut o = new_oscilloscope_view(8);
osv_set_time_div(&mut o, -1.0);
assert!(o.time_div > 0.0 ,);
}
#[test]
fn test_set_enabled() {
let mut o = new_oscilloscope_view(8);
osv_set_enabled(&mut o, false);
assert!(!o.enabled ,);
}
#[test]
fn test_to_json_contains_trigger() {
let o = new_oscilloscope_view(16);
let j = osv_to_json(&o);
assert!(j.contains("\"trigger\""), );
}
#[test]
fn test_enabled_default() {
let o = new_oscilloscope_view(8);
assert!(o.enabled ,);
}
}