1#[derive(Clone, Debug, PartialEq, Eq)]
4pub enum SampleError {
5 HopOutsideCola {
6 window: usize,
7 hop: usize,
8 },
9 WindowNotPowerOfTwo {
10 window: usize,
11 },
12 WidthMismatch {
13 left: usize,
14 right: usize,
15 },
16 ChannelOutOfRange {
17 k: usize,
18 width: usize,
19 },
20 GridTooLarge {
22 model: &'static str,
23 nodes: usize,
24 ceiling: usize,
25 },
26 StringPastRate {
28 model: &'static str,
29 },
30 BridgeUnstable {
32 model: &'static str,
33 },
34 ContactUnsettled {
36 model: &'static str,
37 sample: usize,
38 },
39 ReadsAhead {
41 at: i64,
42 },
43 UnreadablePosition,
45 FormulaUnevaluable {
47 at: i64,
48 },
49 ArgumentOutOfRange {
51 model: &'static str,
52 name: &'static str,
53 bits: u64,
55 sample: u64,
56 },
57}
58
59#[derive(Clone, Debug, PartialEq)]
61pub enum CollapseError {
62 EmptyBand {
64 ceiling: f64,
65 lowest: f64,
66 by_rate: bool,
67 },
68 SingularInCt {
69 at: f64,
70 order: i32,
71 },
72 NotEvaluable(&'static str),
73 NestedSeries {
75 depth: usize,
76 terms: Option<usize>,
77 bound: usize,
78 },
79 LeftAlgebra(&'static str),
80 NoBlockRow,
82}
83
84impl CollapseError {
85 pub fn code(&self) -> &'static str {
86 match self {
87 CollapseError::EmptyBand { .. } => "collapse.empty_band",
88 CollapseError::SingularInCt { .. } => "collapse.singular_in_ct",
89 CollapseError::NotEvaluable(_) => "collapse.not_evaluable",
90 CollapseError::NestedSeries { .. } => "collapse.series_nesting",
91 CollapseError::LeftAlgebra(_) => "cast.left_algebra",
92 CollapseError::NoBlockRow => "collapse.no_block_row",
93 }
94 }
95}
96
97impl CollapseError {
99 pub fn help(&self) -> &'static str {
100 match self {
101 CollapseError::EmptyBand { by_rate: true, .. } => {
102 "this rate's own half is the ceiling: raise --rate past twice the \
103 lowest line"
104 }
105 CollapseError::EmptyBand { .. } => {
106 "the profile's ceiling is what no rate raises; read it with \
107 `--representation lines`, or bring the line into the band"
108 }
109 CollapseError::SingularInCt { .. } => {
110 "write it inside a convolution, or sample the closed form it multiplies"
111 }
112 CollapseError::NestedSeries { .. } => {
113 "write fewer levels, or a narrower band for the terms to clear"
114 }
115 CollapseError::NotEvaluable(_) | CollapseError::LeftAlgebra(_) => {
116 "write the subterm inside sample(...) to leave A deliberately"
117 }
118 CollapseError::NoBlockRow => {
119 "render it to a stated end instead of streaming it, or write it in t"
120 }
121 }
122 }
123}
124
125impl std::fmt::Display for CollapseError {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 match self {
128 CollapseError::EmptyBand {
129 ceiling, lowest, ..
130 } => write!(
131 f,
132 "every line is at or above the {ceiling} Hz ceiling, the lowest at {lowest} Hz"
133 ),
134 CollapseError::SingularInCt { at, order } => write!(
135 f,
136 "a singularity of order {order} at t = {at} has no value on the grid"
137 ),
138 CollapseError::NotEvaluable(what) => {
139 write!(f, "{what} has no value at a point")
140 }
141 CollapseError::NestedSeries {
142 depth,
143 terms,
144 bound,
145 } => match terms {
146 Some(terms) => write!(
147 f,
148 "a series nested {depth} deep takes {terms} terms at one instant, past \
149 the {bound} one expansion holds"
150 ),
151 None => write!(
152 f,
153 "a series nested {depth} deep takes more terms at one instant than a \
154 count holds, past the {bound} one expansion holds"
155 ),
156 },
157 CollapseError::LeftAlgebra(clause) => write!(f, "the closed form left A. {clause}"),
158 CollapseError::NoBlockRow => write!(
159 f,
160 "a closed form in f reaches the grid by one transform over a whole extent, \
161 so no block of it is read alone"
162 ),
163 }
164 }
165}
166
167impl SampleError {
168 pub fn code(&self) -> &'static str {
169 match self {
170 SampleError::HopOutsideCola { .. } => "samples.hop_outside_cola",
171 SampleError::WindowNotPowerOfTwo { .. } => "samples.window_not_power_of_two",
172 SampleError::WidthMismatch { .. } => "type.width_mismatch",
173 SampleError::ChannelOutOfRange { .. } => "samples.channel_out_of_range",
174 SampleError::GridTooLarge { .. } => "samples.grid_too_large",
175 SampleError::StringPastRate { .. } => "samples.string_past_rate",
176 SampleError::BridgeUnstable { .. } => "samples.bridge_unstable",
177 SampleError::ContactUnsettled { .. } => "samples.contact_unsettled",
178 SampleError::ArgumentOutOfRange { .. } => "samples.argument_out_of_range",
179 SampleError::ReadsAhead { .. } => "engine.reads_ahead",
180 SampleError::UnreadablePosition => "engine.unreadable_position",
181 SampleError::FormulaUnevaluable { .. } => "collapse.not_evaluable",
182 }
183 }
184}
185
186impl std::fmt::Display for SampleError {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 match self {
189 SampleError::HopOutsideCola { window, hop } => write!(
190 f,
191 "a window of {window} at a hop of {hop} does not overlap-add to a constant. \
192 write a hop that divides the window"
193 ),
194 SampleError::WindowNotPowerOfTwo { window } => {
195 write!(f, "a window of {window} is not a power of two")
196 }
197 SampleError::WidthMismatch { left, right } => write!(
198 f,
199 "{left} components meet {right}; an elementwise operation needs equal widths, \
200 or one side mono"
201 ),
202 SampleError::ChannelOutOfRange { k, width } => {
203 write!(f, "component {k} of a value {width} wide")
204 }
205 SampleError::GridTooLarge {
206 model,
207 nodes,
208 ceiling,
209 } => write!(
210 f,
211 "`{model}` sizes a {nodes}-node grid at this rate, past the {ceiling} one \
212 call may hold. ask for a higher fundamental, or a lower --rate"
213 ),
214 SampleError::StringPastRate { model } => write!(
215 f,
216 "`{model}` has no stable grid at this rate whose first two partials ring where \
217 asked. ask for a lower fundamental or `b`, or a higher --rate"
218 ),
219 SampleError::BridgeUnstable { model } => write!(
220 f,
221 "`{model}`'s unison is not proven stable on its bridge at this rate: the mass \
222 form its bridge row leaves is not provably positive. ask for a heavier bridge, \
223 less frequency-dependent loss, or a higher --rate"
224 ),
225 SampleError::ContactUnsettled { model, sample } => write!(
226 f,
227 "`{model}`'s contact force settled on no value at sample {sample}. ask for a \
228 lower bow velocity or force, or a higher --rate"
229 ),
230 SampleError::ReadsAhead { at } => write!(
231 f,
232 "a reading needs sample {at} of its source, which is not computed yet: a \
233 stream reads no output ahead of where it stands"
234 ),
235 SampleError::UnreadablePosition => {
236 write!(f, "an exactly computed time passed what its integers hold")
237 }
238 SampleError::FormulaUnevaluable { at } => write!(
239 f,
240 "a closed form read at sample {at}'s instant has no value there"
241 ),
242 SampleError::ArgumentOutOfRange {
243 model,
244 name,
245 bits,
246 sample,
247 } => write!(
248 f,
249 "`{model}`'s `{name}` is {} at sample {sample}, outside the range it models",
250 f64::from_bits(*bits)
251 ),
252 }
253 }
254}