From ebdb8a86a148795084a7ba254f2d41e746299679 Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Fri, 19 Apr 2024 12:13:23 +0200 Subject: [PATCH] Clippy improvements, some comments added, etc. --- src/daq/api/api_cpal.rs | 16 ++++++------ src/daq/daqconfig.rs | 2 +- src/daq/record.rs | 53 +++++++++++++++++++++++++++++++--------- src/daq/streamdata.rs | 2 +- src/daq/streamhandler.rs | 2 +- src/daq/streammgr.rs | 36 ++++++++++++++++----------- src/filter.rs | 4 +-- src/lib.rs | 3 ++- src/siggen.rs | 4 +-- 9 files changed, 80 insertions(+), 42 deletions(-) diff --git a/src/daq/api/api_cpal.rs b/src/daq/api/api_cpal.rs index dcdb44b..5da67bd 100644 --- a/src/daq/api/api_cpal.rs +++ b/src/daq/api/api_cpal.rs @@ -96,7 +96,7 @@ impl CpalApi { let mut oChannelCount = 0; let mut avSampleRates = srs_tot.clone(); - let mut avFramesPerBlock = vec![256 as usize, 512, 1024, 2048, 8192]; + let mut avFramesPerBlock = vec![256_usize, 512, 1024, 2048, 8192]; let mut sample_formats = vec![]; // Search for sample formats @@ -134,7 +134,7 @@ impl CpalApi { } } sample_formats.dedup(); - if sample_formats.len() == 0 { + if sample_formats.is_empty() { continue; } @@ -177,7 +177,8 @@ impl CpalApi { send_ch: Option>, status: Arc>, ) -> impl FnMut(cpal::StreamError) { - let errfn = move |err: cpal::StreamError| { + + move |err: cpal::StreamError| { let serr = match err { cpal::StreamError::DeviceNotAvailable => StreamError::DeviceNotAvailable, cpal::StreamError::BackendSpecific { err: _ } => StreamError::DriverError, @@ -186,8 +187,7 @@ impl CpalApi { sender.send(RawStreamData::StreamError(serr)).unwrap(); } status.store(StreamStatus::Error(serr)); - }; - errfn + } } fn create_incallback( @@ -435,14 +435,14 @@ impl CpalApi { let supported_config = match stype { StreamType::Duplex => bail!("Duplex stream not supported for CPAL"), StreamType::Input => CpalApi::create_cpal_config( - stype.clone(), + stype, devinfo, conf, &cpaldev, cpaldev.supported_input_configs()?, ), StreamType::Output => CpalApi::create_cpal_config( - stype.clone(), + stype, devinfo, conf, &cpaldev, @@ -610,7 +610,7 @@ impl CpalApi { // Create an output stream, using given signal generators for each channel. // } - pub fn startOutputStream(&self, rx: Receiver) -> Result> { + pub fn startOutputStream(&self, _rx: Receiver) -> Result> { bail!("Not implemented"); } } diff --git a/src/daq/daqconfig.rs b/src/daq/daqconfig.rs index f345eb6..f21ff6b 100644 --- a/src/daq/daqconfig.rs +++ b/src/daq/daqconfig.rs @@ -154,7 +154,7 @@ impl DaqConfig { /// /// * st: string containing TOML data. pub fn deserialize_TOML_str(st: &String) -> Result { - let res: DaqConfig = toml::from_str(&st)?; + let res: DaqConfig = toml::from_str(st)?; Ok(res) } diff --git a/src/daq/record.rs b/src/daq/record.rs index 4067c39..29d6ee4 100644 --- a/src/daq/record.rs +++ b/src/daq/record.rs @@ -1,21 +1,21 @@ use super::*; use crate::config::Flt; use anyhow::{bail, Error, Result}; +use clap::builder::OsStr; use crossbeam::atomic::AtomicCell; use hdf5::types::{VarLenArray, VarLenUnicode}; use hdf5::{dataset, datatype, Dataset, File, H5Type}; use ndarray::ArrayView2; -use clap::builder::OsStr; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::atomic::{AtomicBool, Ordering::SeqCst}; use std::sync::{Arc, Mutex}; use std::thread::{spawn, JoinHandle}; use std::time::Duration; -use strum::EnumMessage; +use streamdata::*; use streammgr::*; use streammsg::InStreamMsg; -use streamdata::*; +use strum::EnumMessage; #[derive(Clone, Debug)] /// Status of a recording @@ -51,19 +51,48 @@ pub struct RecordSettings { /// The delay to wait before adding data pub startDelay: Duration, } +impl RecordSettings { + /// Create new record settings. Convenience wrapper to fill in fields in + /// right form. Start delay is optional + /// + /// * args: + /// filename: Name of file to record to + /// duration: How long recording should be. Zero means record indefinitely. + /// startDelay: Optional start delay. + pub fn new(filename: T, duration: U, startDelay: Option) -> RecordSettings + where + T: Into, + U: Into + Default, + { + RecordSettings { + filename: filename.into(), + duration: duration.into(), + startDelay: startDelay + .map(|s| s.into()) + .unwrap_or_else(|| Duration::ZERO), + } + } +} /// This struct lets a recording run on a stream, waits till the first data arrives and records for a given period of time. Usage: /// /// ``` /// use lasprs::{RecordSettings, StreamMgr, Recording}; /// use std::time::Duration; -/// let smgr = StreamMgr::new(); +/// +/// fn main() -> anyhow::Result<()> { +/// let mut smgr = StreamMgr::new(); /// smgr.startDefaultInputStream()?; -/// let settings = RecordSettings{ -/// filename: "test.h5", -/// duration: Duration::from_secs(5), -/// }; -/// let rec = Recording::new(settings)?; +/// +/// // Create record settings +/// let settings = RecordSettings::new( +/// "test.h5", +/// Duration::from_millis(100), +/// None, +/// ); +/// let rec = Recording::new(settings, &mut smgr)?; +/// Ok(()) +/// } /// ``` pub struct Recording { settings: RecordSettings, @@ -82,7 +111,7 @@ impl Recording { where T: H5Type, { - let bs = meta.framesPerBlock as usize; + let bs = meta.framesPerBlock; let nch = meta.nchannels(); match file .new_dataset::() @@ -169,7 +198,7 @@ impl Recording { pub fn new(mut settings: RecordSettings, mgr: &mut StreamMgr) -> Result { // Append extension if not yet there match settings.filename.extension() { - Some(a) if a == OsStr::from("h5") => {} + Some(a) if a == "h5" => {} None | Some(_) => { settings.filename = (settings.filename.to_string_lossy().to_string() + ".h5").into(); @@ -428,7 +457,7 @@ impl Recording { impl Drop for Recording { fn drop(&mut self) { - if let Some(_) = &self.handle { + if self.handle.is_some() { // If we enter here, stop() or cancel() has not been called. In that // case, we cleanup here by cancelling the recording self.cancel(); diff --git a/src/daq/streamdata.rs b/src/daq/streamdata.rs index a348ff4..fb7907e 100644 --- a/src/daq/streamdata.rs +++ b/src/daq/streamdata.rs @@ -38,7 +38,7 @@ pub enum RawStreamData { } impl RawStreamData { - pub fn toFloat(&self, nchannels: usize) -> Dmat { + pub fn toFloat(&self, _nchannels: usize) -> Dmat { // match &self { // RawStreamData::Datai8(c) => { // Dmat::zeros((2, 2)); diff --git a/src/daq/streamhandler.rs b/src/daq/streamhandler.rs index 49326e1..3c3a3bf 100644 --- a/src/daq/streamhandler.rs +++ b/src/daq/streamhandler.rs @@ -16,4 +16,4 @@ impl StreamHandler { smgr.addInQueue(tx); StreamHandler{rx} } -} \ No newline at end of file +} diff --git a/src/daq/streammgr.rs b/src/daq/streammgr.rs index 5ce9fe6..66d907d 100644 --- a/src/daq/streammgr.rs +++ b/src/daq/streammgr.rs @@ -5,9 +5,6 @@ use crate::{ config::*, siggen::{self, Siggen}, }; -use streamcmd::StreamCommand; -use streammsg::*; -use streamdata::*; use anyhow::{bail, Error, Result}; use array_init::from_iter; use core::time; @@ -18,6 +15,9 @@ use crossbeam::{ }; use std::sync::{atomic::AtomicBool, Arc, Mutex}; use std::thread::{JoinHandle, Thread}; +use streamcmd::StreamCommand; +use streamdata::*; +use streammsg::*; #[cfg(feature = "cpal-api")] use super::api::api_cpal::CpalApi; @@ -90,6 +90,12 @@ impl StreamMgr { // } // #[pyo3(name = "firstOrderHighPass")] } +impl Default for StreamMgr { + fn default() -> Self { + Self::new() + } +} + impl StreamMgr { /// Create new stream manager. A stream manager is supposed to be a singleton. /// @@ -116,7 +122,7 @@ impl StreamMgr { smgr.devs = smgr.scanDeviceInfo(); smgr } - + /// Get stream status for given stream type. pub fn getStatus(&self, t: StreamType) -> StreamStatus { match t { @@ -181,7 +187,12 @@ impl StreamMgr { devinfo } - /// Add a new queue to the lists of queues + /// Add a new queue to the lists of queues. On the queue, input data is + /// added. + /// + /// If the stream is unable to write data on the queue (which might + /// happen when the handler is dropped), the queue is removed from the list + /// of queues that get data from the stream. pub fn addInQueue(&mut self, tx: Sender) { if let Some(is) = &self.input_stream { is.comm.send(StreamCommand::AddInQueue(tx)).unwrap() @@ -249,14 +260,9 @@ impl StreamMgr { // Match device info struct on given daq config. fn match_devinfo(&self, cfg: &DaqConfig) -> Option<&DeviceInfo> { - for d in self.devs.iter() { - if d.device_name == cfg.device_name { - return Some(d); - } - } - None + self.devs.iter().find(|&d| d.device_name == cfg.device_name) } - fn startOuputStreamThread( + fn startOuputStreamThread( &mut self, meta: Arc, tx: Sender, @@ -483,7 +489,7 @@ impl StreamMgr { let (tx, rx)= unbounded(); let stream = self.cpal_api.startDefaultOutputStream(rx)?; let meta = stream.metadata(); - let (threadhandle, commtx) = self.startOuputStreamThread::(meta, tx); + let (threadhandle, commtx) = self.startOuputStreamThread(meta, tx); // Inform all listeners of new stream data @@ -532,7 +538,9 @@ impl StreamMgr { comm, }) = self.output_stream.take() { - if let Err(_) = comm.send(StreamCommand::StopThread){ + if comm.send(StreamCommand::StopThread).is_err() { + // Failed to send command over channel. This means the thread is + // already finished due to some other reason. assert!(threadhandle.is_finished()); } // println!("Wainting for threadhandle to join..."); diff --git a/src/filter.rs b/src/filter.rs index 8e89d60..ed1095f 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -168,7 +168,7 @@ impl Filter for Biquad { self.w2 = 0.; } fn clone_dyn(&self) -> Box { - Box::new(self.clone()) + Box::new(*self) } } @@ -191,7 +191,7 @@ impl SeriesBiquad { /// Create new series filter set. See [SeriesBiquad::new()] /// pub fn new_py<'py>(coefs: PyReadonlyArrayDyn) -> PyResult { - Ok(SeriesBiquad::new(&coefs.as_slice()?)?) + Ok(SeriesBiquad::new(coefs.as_slice()?)?) } #[pyo3(name = "unit")] #[staticmethod] diff --git a/src/lib.rs b/src/lib.rs index 5156d8e..68f9335 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ pub mod daq; pub mod siggen; pub use config::*; +pub use daq::*; cfg_if::cfg_if! { if #[cfg(feature = "python-bindings")] { @@ -32,7 +33,7 @@ if #[cfg(feature = "python-bindings")] { #[pyo3(name="_lasprs")] fn lasprs(py: Python, m: &PyModule) -> PyResult<()> { - pyo3_add_submodule_filter(py, &m)?; + pyo3_add_submodule_filter(py, m)?; Ok(()) } diff --git a/src/siggen.rs b/src/siggen.rs index bdd6ca7..598b7e2 100644 --- a/src/siggen.rs +++ b/src/siggen.rs @@ -352,7 +352,7 @@ impl SiggenChannelConfig { } else { result.copy_from_slice(source); if let Some(f) = &mut self.prefilter { - f.filter(&result); + f.filter(result); } } result.iter_mut().for_each(|x| { @@ -428,7 +428,7 @@ mod test { fn test_sample() { assert_eq!(0.5f32.to_sample::(), 64); assert_eq!(1.0f32.to_sample::(), 127); - assert_eq!(-1.0f32.to_sample::(), -127); + assert_eq!(-(1.0f32.to_sample::()), -127); assert_eq!(1.0f32.to_sample::(), i16::MAX); } }