#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SampleError {
HopOutsideCola {
window: usize,
hop: usize,
},
WindowNotPowerOfTwo {
window: usize,
},
WidthMismatch {
left: usize,
right: usize,
},
ChannelOutOfRange {
k: usize,
width: usize,
},
GridTooLarge {
model: &'static str,
nodes: usize,
ceiling: usize,
},
}
#[derive(Clone, Debug, PartialEq)]
pub enum CollapseError {
NoHorizon,
EmptyBand {
ceiling: f64,
lowest: f64,
},
SingularInCt {
at: f64,
order: i32,
},
NotEvaluable(&'static str),
NestedSeries {
depth: usize,
terms: usize,
bound: usize,
},
LeftAlgebra(&'static str),
}
impl CollapseError {
pub fn code(&self) -> &'static str {
match self {
CollapseError::NoHorizon => "collapse.no_horizon",
CollapseError::EmptyBand { .. } => "collapse.empty_band",
CollapseError::SingularInCt { .. } => "collapse.singular_in_ct",
CollapseError::NotEvaluable(_) => "collapse.not_evaluable",
CollapseError::NestedSeries { .. } => "collapse.series_nesting",
CollapseError::LeftAlgebra(_) => "cast.left_algebra",
}
}
}
impl CollapseError {
pub fn help(&self) -> &'static str {
match self {
CollapseError::NoHorizon => "give the observation a window with --from and --to",
CollapseError::EmptyBand { ceiling, .. }
if *ceiling < sva_formula::AUDIBLE_CEILING_HZ =>
{
"this rate's own half is the ceiling: raise --sample-rate past twice the \
lowest line"
}
CollapseError::EmptyBand { .. } => {
"the profile's 20 kHz ceiling is what no rate raises; read it with \
`--as lines`, or bring the line into the band"
}
CollapseError::SingularInCt { .. } => {
"write it inside a convolution, or sample the closed form it multiplies"
}
CollapseError::NestedSeries { .. } => {
"write fewer levels, or a narrower band for the terms to clear"
}
CollapseError::NotEvaluable(_) | CollapseError::LeftAlgebra(_) => {
"write the subterm inside sample(...) to leave A deliberately"
}
}
}
}
impl std::fmt::Display for CollapseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CollapseError::NoHorizon => {
write!(
f,
"a closed form collapses against a horizon. give --from and --to"
)
}
CollapseError::EmptyBand { ceiling, lowest } => write!(
f,
"every line is at or above the {ceiling} Hz ceiling, the lowest at {lowest} Hz"
),
CollapseError::SingularInCt { at, order } => write!(
f,
"a singularity of order {order} at t = {at} has no value on the grid"
),
CollapseError::NotEvaluable(what) => {
write!(f, "{what} has no value at a point")
}
CollapseError::NestedSeries {
depth,
terms,
bound,
} => write!(
f,
"a series nested {depth} deep takes {terms} terms at one instant, past the \
{bound} one expansion holds"
),
CollapseError::LeftAlgebra(clause) => write!(f, "the closed form left A. {clause}"),
}
}
}
impl SampleError {
pub fn code(&self) -> &'static str {
match self {
SampleError::HopOutsideCola { .. } => "samples.hop_outside_cola",
SampleError::WindowNotPowerOfTwo { .. } => "samples.window_not_power_of_two",
SampleError::WidthMismatch { .. } => "type.width_mismatch",
SampleError::ChannelOutOfRange { .. } => "samples.channel_out_of_range",
SampleError::GridTooLarge { .. } => "samples.grid_too_large",
}
}
}
impl std::fmt::Display for SampleError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SampleError::HopOutsideCola { window, hop } => write!(
f,
"a window of {window} at a hop of {hop} does not overlap-add to a constant. \
write a hop that divides the window"
),
SampleError::WindowNotPowerOfTwo { window } => {
write!(f, "a window of {window} is not a power of two")
}
SampleError::WidthMismatch { left, right } => write!(
f,
"{left} components meet {right}; an elementwise operation needs equal widths, \
or one side mono"
),
SampleError::ChannelOutOfRange { k, width } => {
write!(f, "component {k} of a value {width} wide")
}
SampleError::GridTooLarge {
model,
nodes,
ceiling,
} => write!(
f,
"`{model}` sizes a {nodes}-node grid at this rate, past the {ceiling} one \
call may hold. ask for a higher fundamental, or a lower --sample-rate"
),
}
}
}