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