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