1use std::convert::Infallible;
2
3use thiserror::Error as ThisError;
4
5pub type Result<T, E = Error> = std::result::Result<T, E>;
7
8#[derive(Clone, Debug, Eq, PartialEq, ThisError)]
10#[non_exhaustive]
11pub enum Error {
12 #[error("Music21Object error: {0}")]
14 Music21Object(String),
15 #[error("Chord error: {0}")]
17 Chord(String),
18 #[error("Pitch error: {0}")]
20 Pitch(String),
21 #[error("Microtone error: {0}")]
23 Microtone(String),
24 #[error("Accidental error: {0}")]
26 Accidental(String),
27 #[error("ChordTables error: {0}")]
29 ChordTables(String),
30 #[error("Interval error: {0}")]
32 Interval(String),
33 #[error("StepName error: {0}")]
35 StepName(String),
36 #[error("PitchClass error: {0}")]
38 PitchClass(String),
39 #[error("Ordinal error: {0}")]
41 Ordinal(String),
42 #[error("Polyrhythm error: {0}")]
44 Polyrhythm(String),
45 #[error("TuningSystem error: {0}")]
47 TuningSystem(String),
48 #[error("Midi error: {0}")]
50 Midi(String),
51 #[error("Analysis error: {0}")]
53 Analysis(String),
54 #[error("Meter error: {0}")]
56 Meter(String),
57 #[error("Sieve error: {0}")]
59 Sieve(String),
60 #[error("Duration error: {0}")]
62 Duration(String),
63 #[error("Key error: {0}")]
65 Key(String),
66 #[error("Scale error: {0}")]
68 Scale(String),
69 #[error("Tempo error: {0}")]
71 Tempo(String),
72 #[error("Instrument error: {0}")]
74 Instrument(String),
75 #[error("Figured bass error: {0}")]
77 FiguredBass(String),
78 #[error("ABC error: {0}")]
80 Abc(String),
81 #[error("Humdrum error: {0}")]
83 Humdrum(String),
84 #[error("XML error: {0}")]
86 Xml(String),
87 #[error("MEI error: {0}")]
89 Mei(String),
90 #[error("RomanText error: {0}")]
92 RomanText(String),
93 #[error("Capella error: {0}")]
95 Capella(String),
96 #[error("MuseData error: {0}")]
98 MuseData(String),
99 #[error("NoteWorthy error: {0}")]
101 Noteworthy(String),
102 #[error("MuseScore error: {0}")]
105 MuseScore(String),
106 #[error("Expression error: {0}")]
108 Expression(String),
109 #[error("Clef error: {0}")]
111 Clef(String),
112 #[error("Serial error: {0}")]
114 Serial(String),
115 #[error("Notation error: {0}")]
117 Notation(String),
118 #[error("Volume error: {0}")]
120 Volume(String),
121 #[error("Stream error: {0}")]
124 Stream(String),
125
126 #[error("Feature error: {0}")]
129 Feature(String),
130 #[error("Text error: {0}")]
133 Text(String),
134 #[error("Search error: {0}")]
137 Search(String),
138 #[error("Tablature error: {0}")]
141 Tablature(String),
142 #[error("Tree error: {0}")]
145 Tree(String),
146 #[error("OMR error: {0}")]
150 Omr(String),
151 #[error("Variant error: {0}")]
155 Variant(String),
156 #[cfg(feature = "musicxml")]
158 #[error("MusicXML export error: {0}")]
159 MusicXml(String),
160 #[error("Value error: {0}")]
167 Value(String),
168}
169
170impl From<Infallible> for Error {
171 fn from(value: Infallible) -> Self {
172 match value {}
173 }
174}
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179 use std::error::Error as StdError;
180
181 #[test]
182 fn test_display_music21object() {
183 let err = Error::Music21Object("error message".to_string());
184 assert_eq!(format!("{err}"), "Music21Object error: error message");
185 }
186
187 #[test]
188 fn test_display_chord() {
189 let err = Error::Chord("chord error".to_string());
190 assert_eq!(format!("{err}"), "Chord error: chord error");
191 }
192
193 #[test]
194 fn test_display_pitch() {
195 let err = Error::Pitch("pitch error".to_string());
196 assert_eq!(format!("{err}"), "Pitch error: pitch error");
197 }
198
199 #[test]
200 fn test_display_microtone() {
201 let err = Error::Microtone("microtone error".to_string());
202 assert_eq!(format!("{err}"), "Microtone error: microtone error");
203 }
204
205 #[test]
206 fn test_display_accidental() {
207 let err = Error::Accidental("accidental error".to_string());
208 assert_eq!(format!("{err}"), "Accidental error: accidental error");
209 }
210
211 #[test]
212 fn test_display_chordtables() {
213 let err = Error::ChordTables("chordtables error".to_string());
214 assert_eq!(format!("{err}"), "ChordTables error: chordtables error");
215 }
216
217 #[test]
218 fn test_display_interval() {
219 let err = Error::Interval("interval error".to_string());
220 assert_eq!(format!("{err}"), "Interval error: interval error");
221 }
222
223 #[test]
224 fn test_display_stepname() {
225 let err = Error::StepName("step name error".to_string());
226 assert_eq!(format!("{err}"), "StepName error: step name error");
227 }
228
229 #[test]
230 fn test_display_ordinal() {
231 let err = Error::Ordinal("ordinal error".to_string());
232 assert_eq!(format!("{err}"), "Ordinal error: ordinal error");
233 }
234
235 #[test]
236 fn test_display_polyrhythm() {
237 let err = Error::Polyrhythm("polyrhythm error".to_string());
238 assert_eq!(format!("{err}"), "Polyrhythm error: polyrhythm error");
239 }
240
241 #[test]
242 fn test_display_tuningsystem() {
243 let err = Error::TuningSystem("tuning system error".to_string());
244 assert_eq!(format!("{err}"), "TuningSystem error: tuning system error");
245 }
246
247 #[test]
248 fn test_source_none() {
249 let errors = [
250 Error::Music21Object("music21".to_string()),
251 Error::Chord("chord".to_string()),
252 Error::Pitch("pitch".to_string()),
253 Error::Microtone("microtone".to_string()),
254 Error::Accidental("accidental".to_string()),
255 Error::ChordTables("chordtables".to_string()),
256 Error::Interval("interval".to_string()),
257 Error::StepName("step".to_string()),
258 Error::PitchClass("pitch class".to_string()),
259 Error::Ordinal("ordinal".to_string()),
260 Error::Polyrhythm("polyrhythm".to_string()),
261 Error::TuningSystem("tuning system".to_string()),
262 Error::Midi("midi".to_string()),
263 Error::Analysis("analysis".to_string()),
264 ];
265
266 for err in errors.iter() {
267 assert!(
269 err.source().is_none(),
270 "Expected None for source() in {err:?}"
271 );
272 }
273 }
274
275 #[test]
276 fn test_all_errors_display() {
277 let cases = [
278 (
279 Error::Music21Object("music21".to_string()),
280 "Music21Object error: music21",
281 ),
282 (Error::Chord("chord".to_string()), "Chord error: chord"),
283 (Error::Pitch("pitch".to_string()), "Pitch error: pitch"),
284 (
285 Error::Microtone("microtone".to_string()),
286 "Microtone error: microtone",
287 ),
288 (
289 Error::Accidental("accidental".to_string()),
290 "Accidental error: accidental",
291 ),
292 (
293 Error::ChordTables("chordtables".to_string()),
294 "ChordTables error: chordtables",
295 ),
296 (
297 Error::Interval("interval".to_string()),
298 "Interval error: interval",
299 ),
300 (Error::StepName("step".to_string()), "StepName error: step"),
301 (
302 Error::PitchClass("pitchclass".to_string()),
303 "PitchClass error: pitchclass",
304 ),
305 (
306 Error::Ordinal("ordinal".to_string()),
307 "Ordinal error: ordinal",
308 ),
309 (
310 Error::Polyrhythm("polyrhythm".to_string()),
311 "Polyrhythm error: polyrhythm",
312 ),
313 (
314 Error::TuningSystem("tuning system".to_string()),
315 "TuningSystem error: tuning system",
316 ),
317 (Error::Midi("midi".to_string()), "Midi error: midi"),
318 (
319 Error::Analysis("analysis".to_string()),
320 "Analysis error: analysis",
321 ),
322 (Error::Serial("serial".to_string()), "Serial error: serial"),
323 ];
324
325 for (err, expected) in cases.iter() {
326 assert_eq!(format!("{err}"), *expected);
327 assert!(err.source().is_none());
328 }
329 }
330}