use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
EmptyInput,
InsufficientData { required: usize, provided: usize },
NonFiniteSignal,
SignalTooWeak { rms: f64, threshold: f64 },
MorseDecodeFailed { reason: String },
DdmComputationFailed { reason: String },
SignalProcessing { reason: String },
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::EmptyInput => write!(f, "input signal is empty"),
Error::InsufficientData { required, provided } => {
write!(
f,
"insufficient data: need {required} samples, got {provided}"
)
}
Error::NonFiniteSignal => write!(f, "signal contains NaN or infinity"),
Error::SignalTooWeak { rms, threshold } => {
write!(
f,
"signal too weak (RMS {rms:.2e} < threshold {threshold:.2e})"
)
}
Error::MorseDecodeFailed { reason } => write!(f, "Morse decode failed: {reason}"),
Error::DdmComputationFailed { reason } => write!(f, "DDM computation failed: {reason}"),
Error::SignalProcessing { reason } => write!(f, "signal processing error: {reason}"),
}
}
}
impl std::error::Error for Error {}
#[derive(Debug, Clone, PartialEq)]
pub struct VorRadialResult {
pub radial: f64,
pub confidence: f64,
pub to_from: Option<VorToFrom>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VorToFrom {
To,
From,
}
#[derive(Debug, Clone)]
pub struct VorTrackResult {
pub radial: f64,
pub cdi: f64,
pub to_from: Option<VorToFrom>,
pub signal_quality: VorSignalQuality,
}
#[derive(Debug, Clone)]
pub struct VorSignalQuality {
pub ref_level: f64,
pub var_level: f64,
pub modulation_index: f64,
}
#[derive(Debug, Clone)]
pub struct IlsDdmResult {
pub ddm: f64,
pub mod_90_hz: f64,
pub mod_150_hz: f64,
pub carrier_strength: f64,
}
#[derive(Debug, Clone)]
pub struct MorseDecodeResult {
pub ident: String,
pub confidence: f64,
pub decode_count: usize,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = Error::EmptyInput;
assert_eq!(err.to_string(), "input signal is empty");
let err = Error::InsufficientData {
required: 1000,
provided: 500,
};
assert_eq!(
err.to_string(),
"insufficient data: need 1000 samples, got 500"
);
let err = Error::SignalTooWeak {
rms: 1e-3,
threshold: 1e-2,
};
assert!(err.to_string().contains("signal too weak"));
}
#[test]
fn test_error_eq() {
let err1 = Error::EmptyInput;
let err2 = Error::EmptyInput;
assert_eq!(err1, err2);
}
}