Skip to main content

dspk_ops/
error.rs

1//! The one error type of dspk-ops.
2
3use dspk_core::DspError;
4use thiserror::Error;
5
6/// `Result` of dspk-ops.
7pub type OpsResult<T> = Result<T, OpsError>;
8
9/// Why a dspk-ops operation could not run: invalid filter parameters, or an error from dspk-core
10/// (shapes, formats).
11#[derive(Debug, Clone, PartialEq, Error)]
12pub enum OpsError {
13    #[error("sample rate must be positive and finite, got {0}")]
14    InvalidSampleRate(f64),
15    #[error("filter order must be at least 1")]
16    InvalidOrder,
17    #[error("cutoff {cutoff_hz} Hz must lie in (0, {nyquist_hz}) Hz")]
18    CutoffOutOfRange { cutoff_hz: f64, nyquist_hz: f64 },
19    #[error("band edges must satisfy low < high, got {low_hz} Hz and {high_hz} Hz")]
20    InvalidBand { low_hz: f64, high_hz: f64 },
21    #[error("quality factor must be positive and finite, got {0}")]
22    InvalidQ(f64),
23    #[error("pass-band ripple must be positive and finite dB, got {0}")]
24    InvalidRipple(f64),
25    #[error("second-order sections must be non-empty, finite, with a0 = 1 and stable poles")]
26    InvalidSections,
27    #[error("forward-backward filters need future samples and cannot run on a live stream")]
28    ForwardBackwardOnLiveStream,
29    #[error("channel order: {0}")]
30    InvalidChannelOrder(String),
31    #[error("{stage} is made for {expected} channels; the data has {actual}")]
32    SpatialChannelMismatch { stage: &'static str, expected: usize, actual: usize },
33    #[error(transparent)]
34    Core(#[from] DspError),
35}
36
37/// Lets `?` pass an [`OpsError`] up through code that returns dspk-core's `DspResult` (readers,
38/// sorters): core errors come back as they were, the others as `InvalidConfig`.
39impl From<OpsError> for DspError {
40    fn from(e: OpsError) -> Self {
41        match e {
42            OpsError::Core(e) => e,
43            other => DspError::InvalidConfig(other.to_string()),
44        }
45    }
46}