Skip to main content

refeff_io/
error.rs

1use std::path::PathBuf;
2
3pub type Result<T> = std::result::Result<T, IoError>;
4
5#[derive(Debug, thiserror::Error)]
6#[non_exhaustive]
7pub enum IoError {
8    #[error("codec error for {path}: {source}")]
9    Codec {
10        path: PathBuf,
11        #[source]
12        source: Box<IoError>,
13    },
14    #[error("invalid strict PAD value {value} at width {width}: {message}")]
15    InvalidPadValue {
16        value: f64,
17        width: usize,
18        message: String,
19    },
20    #[error("I/O error for {path}: {source}")]
21    Io {
22        path: PathBuf,
23        #[source]
24        source: std::io::Error,
25    },
26
27    #[error("too many nested include/load files while reading {path}")]
28    IncludeDepth { path: PathBuf },
29
30    #[error("recursive include/load of {path}")]
31    RecursiveInclude { path: PathBuf },
32
33    #[error("{path}:{line}: {message}")]
34    Parse {
35        path: PathBuf,
36        line: usize,
37        message: String,
38    },
39
40    #[error("failed to format FEFF text output")]
41    Format {
42        #[source]
43        source: std::fmt::Error,
44    },
45
46    #[error(
47        "invalid potential output shape for {field}: got {rows}x{cols}, expected at least {min_rows}x{min_cols}"
48    )]
49    PotentialOutputShape {
50        field: &'static str,
51        rows: usize,
52        cols: usize,
53        min_rows: usize,
54        min_cols: usize,
55    },
56
57    #[error("invalid potential output value for {field}: {message}")]
58    InvalidPotentialOutput {
59        field: &'static str,
60        message: String,
61    },
62
63    #[error(
64        "invalid MTDP shape for {field}: got {rows}x{cols}, expected {expected_rows}x{expected_cols}"
65    )]
66    MtdpShape {
67        field: &'static str,
68        rows: usize,
69        cols: usize,
70        expected_rows: usize,
71        expected_cols: usize,
72    },
73
74    #[error("invalid MTDP length for {field}: got {len}, expected {expected}")]
75    MtdpLength {
76        field: &'static str,
77        len: usize,
78        expected: usize,
79    },
80
81    #[error("missing MTDP field {field}")]
82    MtdpMissing { field: &'static str },
83
84    #[error("could not parse MTDP field {field} from token {token:?}")]
85    MtdpParse { field: &'static str, token: String },
86
87    #[error("invalid MTDP value for {field}: {message}")]
88    InvalidMtdp {
89        field: &'static str,
90        message: String,
91    },
92
93    #[error("MTDP input has {count} trailing token(s)")]
94    MtdpTrailingTokens { count: usize },
95
96    #[error("invalid pot.bin shape for {field}: got {actual:?}, expected {expected:?}")]
97    PotBinShape {
98        field: &'static str,
99        actual: Vec<usize>,
100        expected: Vec<usize>,
101    },
102
103    #[error("missing pot.bin field {field}")]
104    PotBinMissing { field: &'static str },
105
106    #[error("could not parse pot.bin field {field} from token {token:?}")]
107    PotBinParse { field: &'static str, token: String },
108
109    #[error("invalid pot.bin value for {field}: {message}")]
110    InvalidPotBin {
111        field: &'static str,
112        message: String,
113    },
114
115    #[error("pot.bin input has {count} trailing line(s)")]
116    PotBinTrailingLines { count: usize },
117
118    #[error("could not parse apot.bin field {field} on line {line} from token {token:?}")]
119    ApotBinParse {
120        field: &'static str,
121        line: usize,
122        token: String,
123    },
124
125    #[error("invalid apot.bin data on line {line}: {message}")]
126    InvalidApotBin { line: usize, message: String },
127
128    #[error("invalid emesh.bin data: {message}")]
129    InvalidEmeshBin { message: String },
130
131    #[error("invalid specfunct.dat data: {message}")]
132    InvalidSpecfunctDat { message: String },
133
134    #[error("specfunct.dat spectral interpolation failed: {source}")]
135    SpecfunctDatInterpolation {
136        #[source]
137        source: refeff_core::SfconvError,
138    },
139
140    #[error("specfunct.dat EXAFS convolution failed: {source}")]
141    SpecfunctDatExafsConvolution {
142        #[source]
143        source: refeff_core::SfconvError,
144    },
145
146    #[error("specfunct.dat XANES convolution failed: {source}")]
147    SpecfunctDatXanesConvolution {
148        #[source]
149        source: refeff_core::SfconvError,
150    },
151
152    #[error("invalid gtrNN.bin data: {message}")]
153    InvalidGtrBin { message: String },
154
155    #[error("invalid chia.bin data: {message}")]
156    InvalidChiaBin { message: String },
157
158    #[error("invalid phase.bin shape for {field}: got {actual:?}, expected {expected:?}")]
159    PhaseBinShape {
160        field: &'static str,
161        actual: Vec<usize>,
162        expected: Vec<usize>,
163    },
164
165    #[error("missing phase.bin field {field}")]
166    PhaseBinMissing { field: &'static str },
167
168    #[error("could not parse phase.bin field {field} from token {token:?}")]
169    PhaseBinParse { field: &'static str, token: String },
170
171    #[error("invalid phase.bin value for {field}: {message}")]
172    InvalidPhaseBin {
173        field: &'static str,
174        message: String,
175    },
176
177    #[error("invalid rl.dat data for {field}: {message}")]
178    InvalidXsphRlDat {
179        field: &'static str,
180        message: String,
181    },
182
183    #[error("phase.bin input has {count} trailing line(s)")]
184    PhaseBinTrailingLines { count: usize },
185
186    #[error("BAND phase/search setup failed: {source}")]
187    BandSetup {
188        #[source]
189        source: refeff_core::BandError,
190    },
191
192    #[error("invalid feff.bin shape for {field}: got {actual:?}, expected {expected:?}")]
193    FeffBinShape {
194        field: &'static str,
195        actual: Vec<usize>,
196        expected: Vec<usize>,
197    },
198
199    #[error("missing feff.bin field {field}")]
200    FeffBinMissing { field: &'static str },
201
202    #[error("could not parse feff.bin field {field} from token {token:?}")]
203    FeffBinParse { field: &'static str, token: String },
204
205    #[error("invalid feff.bin value for {field}: {message}")]
206    InvalidFeffBin {
207        field: &'static str,
208        message: String,
209    },
210
211    #[error("missing list.dat field {field}")]
212    ListDatMissing { field: &'static str },
213
214    #[error("could not parse list.dat field {field} on line {line} from token {token:?}")]
215    ListDatParse {
216        field: &'static str,
217        line: usize,
218        token: String,
219    },
220
221    #[error("list.dat row on line {line} has {actual} token(s), expected {expected}")]
222    ListDatRowWidth {
223        line: usize,
224        actual: usize,
225        expected: usize,
226    },
227
228    #[error("invalid list.dat value for {field}: {message}")]
229    InvalidListDat {
230        field: &'static str,
231        message: String,
232    },
233
234    #[error("missing nstar.dat field {field}")]
235    NStarDatMissing { field: &'static str },
236
237    #[error("could not parse nstar.dat field {field} on line {line} from token {token:?}")]
238    NStarDatParse {
239        field: &'static str,
240        line: usize,
241        token: String,
242    },
243
244    #[error("nstar.dat row on line {line} has {actual} token(s), expected {expected}")]
245    NStarDatRowWidth {
246        line: usize,
247        actual: usize,
248        expected: usize,
249    },
250
251    #[error("invalid nstar.dat value for {field}: {message}")]
252    InvalidNStarDat {
253        field: &'static str,
254        message: String,
255    },
256
257    #[error("invalid xsect.dat shape for {field}: got {actual}, expected {expected}")]
258    XsectDatShape {
259        field: &'static str,
260        actual: usize,
261        expected: usize,
262    },
263
264    #[error("missing xsect.dat field {field}")]
265    XsectDatMissing { field: &'static str },
266
267    #[error("could not parse xsect.dat field {field} on line {line} from token {token:?}")]
268    XsectDatParse {
269        field: &'static str,
270        line: usize,
271        token: String,
272    },
273
274    #[error("xsect.dat row on line {line} has {actual} token(s), expected {expected}")]
275    XsectDatRowWidth {
276        line: usize,
277        actual: usize,
278        expected: usize,
279    },
280
281    #[error("invalid xsect.dat value for {field}: {message}")]
282    InvalidXsectDat {
283        field: &'static str,
284        message: String,
285    },
286
287    #[error("invalid xsedge.dat shape for {field}: got {actual}, expected {expected}")]
288    XsedgeDatShape {
289        field: &'static str,
290        actual: usize,
291        expected: usize,
292    },
293
294    #[error("could not parse xsedge.dat field {field} on line {line} from token {token:?}")]
295    XsedgeDatParse {
296        field: &'static str,
297        line: usize,
298        token: String,
299    },
300
301    #[error("xsedge.dat row on line {line} has {actual} token(s), expected {expected}")]
302    XsedgeDatRowWidth {
303        line: usize,
304        actual: usize,
305        expected: &'static str,
306    },
307
308    #[error("invalid xsedge.dat value for {field}: {message}")]
309    InvalidXsedgeDat {
310        field: &'static str,
311        message: String,
312    },
313
314    #[error("invalid axafs.dat shape for {field}: got {actual}, expected {expected}")]
315    AxafsDatShape {
316        field: &'static str,
317        actual: usize,
318        expected: usize,
319    },
320
321    #[error("could not parse axafs.dat field {field} on line {line} from token {token:?}")]
322    AxafsDatParse {
323        field: &'static str,
324        line: usize,
325        token: String,
326    },
327
328    #[error("axafs.dat row on line {line} has {actual} token(s), expected {expected}")]
329    AxafsDatRowWidth {
330        line: usize,
331        actual: usize,
332        expected: usize,
333    },
334
335    #[error("invalid axafs.dat value for {field}: {message}")]
336    InvalidAxafsDat {
337        field: &'static str,
338        message: String,
339    },
340
341    #[error("invalid xmu.dat shape for {field}: got {actual}, expected {expected}")]
342    XmuDatShape {
343        field: &'static str,
344        actual: usize,
345        expected: usize,
346    },
347
348    #[error("could not parse xmu.dat field {field} on line {line} from token {token:?}")]
349    XmuDatParse {
350        field: &'static str,
351        line: usize,
352        token: String,
353    },
354
355    #[error("xmu.dat row on line {line} has {actual} token(s), expected {expected}")]
356    XmuDatRowWidth {
357        line: usize,
358        actual: usize,
359        expected: usize,
360    },
361
362    #[error("invalid xmu.dat value for {field}: {message}")]
363    InvalidXmuDat {
364        field: &'static str,
365        message: String,
366    },
367
368    #[error("invalid xmul.dat shape for {field}: got {actual:?}, expected {expected:?}")]
369    XmulDatShape {
370        field: &'static str,
371        actual: Vec<usize>,
372        expected: Vec<usize>,
373    },
374
375    #[error("could not parse xmul.dat field {field} on line {line} from token {token:?}")]
376    XmulDatParse {
377        field: &'static str,
378        line: usize,
379        token: String,
380    },
381
382    #[error("xmul.dat row on line {line} has {actual} token(s), expected {expected}")]
383    XmulDatRowWidth {
384        line: usize,
385        actual: usize,
386        expected: usize,
387    },
388
389    #[error("invalid xmul.dat value for {field}: {message}")]
390    InvalidXmulDat {
391        field: &'static str,
392        message: String,
393    },
394
395    #[error("invalid FEFF run-output value for {field}: {message}")]
396    InvalidRunOutput {
397        field: &'static str,
398        message: String,
399    },
400
401    #[error("invalid chi.dat shape for {field}: got {actual}, expected {expected}")]
402    ChiDatShape {
403        field: &'static str,
404        actual: usize,
405        expected: usize,
406    },
407
408    #[error("could not parse chi.dat field {field} on line {line} from token {token:?}")]
409    ChiDatParse {
410        field: &'static str,
411        line: usize,
412        token: String,
413    },
414
415    #[error("chi.dat row on line {line} has {actual} token(s), expected {expected}")]
416    ChiDatRowWidth {
417        line: usize,
418        actual: usize,
419        expected: &'static str,
420    },
421
422    #[error("invalid chi.dat value for {field}: {message}")]
423    InvalidChiDat {
424        field: &'static str,
425        message: String,
426    },
427
428    #[error("invalid eels.dat shape for {field}: got {actual}, expected {expected}")]
429    EelsDatShape {
430        field: &'static str,
431        actual: usize,
432        expected: usize,
433    },
434
435    #[error(
436        "invalid eels.dat tensor shape: got {rows}x{cols}, expected {expected_rows}x{expected_cols}"
437    )]
438    EelsDatTensorShape {
439        rows: usize,
440        cols: usize,
441        expected_rows: usize,
442        expected_cols: usize,
443    },
444
445    #[error("could not parse eels.dat field {field} on line {line} from token {token:?}")]
446    EelsDatParse {
447        field: &'static str,
448        line: usize,
449        token: String,
450    },
451
452    #[error("eels.dat row on line {line} has {actual} token(s), expected {expected}")]
453    EelsDatRowWidth {
454        line: usize,
455        actual: usize,
456        expected: &'static str,
457    },
458
459    #[error("invalid eels.dat value for {field}: {message}")]
460    InvalidEelsDat {
461        field: &'static str,
462        message: String,
463    },
464
465    #[error("invalid danes.dat shape for {field}: got {actual}, expected {expected}")]
466    DanesDatShape {
467        field: &'static str,
468        actual: usize,
469        expected: usize,
470    },
471
472    #[error("could not parse danes.dat field {field} on line {line} from token {token:?}")]
473    DanesDatParse {
474        field: &'static str,
475        line: usize,
476        token: String,
477    },
478
479    #[error("danes.dat row on line {line} has {actual} token(s), expected {expected}")]
480    DanesDatRowWidth {
481        line: usize,
482        actual: usize,
483        expected: usize,
484    },
485
486    #[error("invalid danes.dat value for {field}: {message}")]
487    InvalidDanesDat {
488        field: &'static str,
489        message: String,
490    },
491
492    #[error(
493        "invalid ldosNN.dat shape for {field}: got {rows}x{cols}, expected {expected_rows}x{expected_cols}"
494    )]
495    LdosDatShape {
496        field: &'static str,
497        rows: usize,
498        cols: usize,
499        expected_rows: usize,
500        expected_cols: &'static str,
501    },
502
503    #[error("could not parse ldosNN.dat field {field} on line {line} from token {token:?}")]
504    LdosDatParse {
505        field: &'static str,
506        line: usize,
507        token: String,
508    },
509
510    #[error("ldosNN.dat row on line {line} has {actual} token(s), expected {expected}")]
511    LdosDatRowWidth {
512        line: usize,
513        actual: usize,
514        expected: &'static str,
515    },
516
517    #[error("invalid ldosNN.dat value for {field}: {message}")]
518    InvalidLdosDat {
519        field: &'static str,
520        message: String,
521    },
522
523    #[error("missing log.dat field {field}")]
524    LogDatMissing { field: &'static str },
525
526    #[error("could not parse log.dat field {field} on line {line} from token {token:?}")]
527    LogDatParse {
528        field: &'static str,
529        line: usize,
530        token: String,
531    },
532
533    #[error("invalid log.dat value for {field}: {message}")]
534    InvalidLogDat {
535        field: &'static str,
536        message: String,
537    },
538
539    #[error("invalid misc.dat line {line}: {message}")]
540    InvalidMiscDat { line: usize, message: String },
541
542    #[error("invalid compton.dat shape for {field}: got {actual}, expected {expected}")]
543    ComptonDatShape {
544        field: &'static str,
545        actual: usize,
546        expected: usize,
547    },
548
549    #[error("could not parse compton.dat field {field} on line {line} from token {token:?}")]
550    ComptonDatParse {
551        field: &'static str,
552        line: usize,
553        token: String,
554    },
555
556    #[error("compton.dat row on line {line} has {actual} token(s), expected {expected}")]
557    ComptonDatRowWidth {
558        line: usize,
559        actual: usize,
560        expected: usize,
561    },
562
563    #[error("invalid compton.dat value for {field}: {message}")]
564    InvalidComptonDat {
565        field: &'static str,
566        message: String,
567    },
568
569    #[error("invalid rhozzp.dat shape for {field}: got {actual}, expected {expected}")]
570    RhozzpDatShape {
571        field: &'static str,
572        actual: usize,
573        expected: usize,
574    },
575
576    #[error("could not parse rhozzp.dat field {field} on line {line} from token {token:?}")]
577    RhozzpDatParse {
578        field: &'static str,
579        line: usize,
580        token: String,
581    },
582
583    #[error("rhozzp.dat row on line {line} has {actual} token(s), expected {expected}")]
584    RhozzpDatRowWidth {
585        line: usize,
586        actual: usize,
587        expected: usize,
588    },
589
590    #[error("invalid rhozzp.dat value for {field}: {message}")]
591    InvalidRhozzpDat {
592        field: &'static str,
593        message: String,
594    },
595
596    #[error(
597        "invalid RHORRP density output shape for {field}: got {rows}x{columns}, expected {expected}"
598    )]
599    RhorrpDensityShape {
600        field: &'static str,
601        rows: usize,
602        columns: usize,
603        expected: &'static str,
604    },
605
606    #[error("invalid RHORRP density output length for {field}: got {actual}, expected {expected}")]
607    RhorrpDensityLength {
608        field: &'static str,
609        actual: usize,
610        expected: usize,
611    },
612
613    #[error(
614        "could not parse RHORRP density output field {field} on line {line} from token {token:?}"
615    )]
616    RhorrpDensityParse {
617        field: &'static str,
618        line: usize,
619        token: String,
620    },
621
622    #[error("RHORRP density output row on line {line} has {actual} token(s), expected {expected}")]
623    RhorrpDensityRowWidth {
624        line: usize,
625        actual: usize,
626        expected: String,
627    },
628
629    #[error("invalid RHORRP density output value for {field}: {message}")]
630    InvalidRhorrpDensity {
631        field: &'static str,
632        message: String,
633    },
634
635    #[error("invalid RHORRP density binary data: {message}")]
636    InvalidRhorrpDensityBin { message: String },
637
638    #[error("invalid RHORRP GG binary data: {message}")]
639    InvalidRhorrpGgBin { message: String },
640
641    #[error("RHORRP density evaluation failed: {source}")]
642    RhorrpDensityEvaluation {
643        #[source]
644        source: refeff_core::RhorrpError,
645    },
646
647    #[error(
648        "invalid jzzp.dat shape for {field}: got {rows}x{cols}, expected {expected_rows}x{expected_cols}"
649    )]
650    JzzpDatShape {
651        field: &'static str,
652        rows: usize,
653        cols: usize,
654        expected_rows: usize,
655        expected_cols: usize,
656    },
657
658    #[error("missing jzzp.dat field {field}")]
659    JzzpDatMissing { field: &'static str },
660
661    #[error("could not parse jzzp.dat field {field} on line {line} from token {token:?}")]
662    JzzpDatParse {
663        field: &'static str,
664        line: usize,
665        token: String,
666    },
667
668    #[error("invalid jzzp.dat value for {field}: {message}")]
669    InvalidJzzpDat {
670        field: &'static str,
671        message: String,
672    },
673
674    #[error("missing crpa.dat field {field}")]
675    CrpaDatMissing { field: &'static str },
676
677    #[error("could not parse crpa.dat field {field} on line {line} from token {token:?}")]
678    CrpaDatParse {
679        field: &'static str,
680        line: usize,
681        token: String,
682    },
683
684    #[error("crpa.dat row on line {line} has {actual} token(s), expected {expected}")]
685    CrpaDatRowWidth {
686        line: usize,
687        actual: usize,
688        expected: usize,
689    },
690
691    #[error("invalid crpa.dat value for {field}: {message}")]
692    InvalidCrpaDat {
693        field: &'static str,
694        message: String,
695    },
696
697    #[error("invalid loss.dat shape for {field}: got {actual}, expected {expected}")]
698    LossDatShape {
699        field: &'static str,
700        actual: usize,
701        expected: usize,
702    },
703
704    #[error("could not parse loss.dat field {field} on line {line} from token {token:?}")]
705    LossDatParse {
706        field: &'static str,
707        line: usize,
708        token: String,
709    },
710
711    #[error("loss.dat row on line {line} has {actual} token(s), expected {expected}")]
712    LossDatRowWidth {
713        line: usize,
714        actual: usize,
715        expected: usize,
716    },
717
718    #[error("invalid loss.dat value for {field}: {message}")]
719    InvalidLossDat {
720        field: &'static str,
721        message: String,
722    },
723
724    #[error("could not parse bphl.dat field {field} on line {line} from token {token:?}")]
725    BphlDatParse {
726        field: &'static str,
727        line: usize,
728        token: String,
729    },
730
731    #[error("bphl.dat row on line {line} has {actual} token(s), expected {expected}")]
732    BphlDatRowWidth {
733        line: usize,
734        actual: usize,
735        expected: usize,
736    },
737
738    #[error("bphl.dat has {actual} record(s), expected {expected}")]
739    BphlDatRecordCount { actual: usize, expected: usize },
740
741    #[error(
742        "bphl.dat {field} mesh value on line {line} is {actual}, expected repeated value {expected}"
743    )]
744    BphlDatMeshMismatch {
745        field: &'static str,
746        line: usize,
747        actual: f64,
748        expected: f64,
749    },
750
751    #[error("invalid bphl.dat reference table: {source}")]
752    BphlDatValidation {
753        #[source]
754        source: refeff_core::ExchangeError,
755    },
756
757    #[error("invalid mpse.dat shape for {field}: got {actual}, expected {expected}")]
758    MpseDatShape {
759        field: &'static str,
760        actual: usize,
761        expected: usize,
762    },
763
764    #[error("could not parse mpse.dat field {field} on line {line} from token {token:?}")]
765    MpseDatParse {
766        field: &'static str,
767        line: usize,
768        token: String,
769    },
770
771    #[error("mpse.dat row on line {line} has {actual} token(s), expected {expected}")]
772    MpseDatRowWidth {
773        line: usize,
774        actual: usize,
775        expected: &'static str,
776    },
777
778    #[error("invalid mpse.dat value for {field}: {message}")]
779    InvalidMpseDat {
780        field: &'static str,
781        message: String,
782    },
783
784    #[error(
785        "invalid RIXS data shape for {field}: got {rows}x{cols}, expected {expected_rows}x{expected_cols}"
786    )]
787    RixsDatShape {
788        field: &'static str,
789        rows: usize,
790        cols: usize,
791        expected_rows: usize,
792        expected_cols: &'static str,
793    },
794
795    #[error("could not parse RIXS data field {field} on line {line} from token {token:?}")]
796    RixsDatParse {
797        field: &'static str,
798        line: usize,
799        token: String,
800    },
801
802    #[error("RIXS data row on line {line} has {actual} token(s), expected {expected}")]
803    RixsDatRowWidth {
804        line: usize,
805        actual: usize,
806        expected: &'static str,
807    },
808
809    #[error("invalid RIXS data value for {field}: {message}")]
810    InvalidRixsDat {
811        field: &'static str,
812        message: String,
813    },
814
815    #[error("invalid fms.bin shape for {field}: got {actual:?}, expected {expected:?}")]
816    FmsBinShape {
817        field: &'static str,
818        actual: Vec<usize>,
819        expected: Vec<usize>,
820    },
821
822    #[error("missing fms.bin field {field}")]
823    FmsBinMissing { field: &'static str },
824
825    #[error("could not parse fms.bin field {field} from token {token:?}")]
826    FmsBinParse { field: &'static str, token: String },
827
828    #[error("invalid fms.bin value for {field}: {message}")]
829    InvalidFmsBin {
830        field: &'static str,
831        message: String,
832    },
833
834    #[error("invalid fmsl.bin shape for {field}: got {actual:?}, expected {expected:?}")]
835    FmslBinShape {
836        field: &'static str,
837        actual: Vec<usize>,
838        expected: Vec<usize>,
839    },
840
841    #[error("invalid fmsl.bin value for {field}: {message}")]
842    InvalidFmslBin {
843        field: &'static str,
844        message: String,
845    },
846
847    #[error("invalid xsecl.bin shape for {field}: got {actual:?}, expected {expected:?}")]
848    XseclBinShape {
849        field: &'static str,
850        actual: Vec<usize>,
851        expected: Vec<usize>,
852    },
853
854    #[error("missing xsecl.bin field {field}")]
855    XseclBinMissing { field: &'static str },
856
857    #[error("could not parse xsecl.bin field {field} on line {line} from token {token:?}")]
858    XseclBinParse {
859        field: &'static str,
860        line: usize,
861        token: String,
862    },
863
864    #[error("xsecl.bin row on line {line} has {actual} token(s), expected {expected}")]
865    XseclBinRowWidth {
866        line: usize,
867        actual: usize,
868        expected: usize,
869    },
870
871    #[error("invalid xsecl.bin value for {field}: {message}")]
872    InvalidXseclBin {
873        field: &'static str,
874        message: String,
875    },
876
877    #[error("invalid feffl.bin shape for {field}: got {actual:?}, expected {expected:?}")]
878    FefflBinShape {
879        field: &'static str,
880        actual: Vec<usize>,
881        expected: Vec<usize>,
882    },
883
884    #[error("invalid feffl.bin value for {field}: {message}")]
885    InvalidFefflBin {
886        field: &'static str,
887        message: String,
888    },
889
890    #[error("missing paths.dat field {field}")]
891    PathsDatMissing { field: &'static str },
892
893    #[error("could not parse paths.dat field {field} on line {line} from token {token:?}")]
894    PathsDatParse {
895        field: &'static str,
896        line: usize,
897        token: String,
898    },
899
900    #[error("paths.dat row on line {line} has {actual} token(s), expected at least {expected}")]
901    PathsDatRowWidth {
902        line: usize,
903        actual: usize,
904        expected: usize,
905    },
906
907    #[error("invalid paths.dat value for {field}: {message}")]
908    InvalidPathsDat {
909        field: &'static str,
910        message: String,
911    },
912
913    #[error("invalid FEFF .dym shape for {field}: got {actual:?}, expected {expected:?}")]
914    DymShape {
915        field: &'static str,
916        actual: Vec<usize>,
917        expected: Vec<usize>,
918    },
919
920    #[error("missing FEFF .dym field {field}")]
921    DymMissing { field: &'static str },
922
923    #[error("could not parse FEFF .dym field {field} on line {line} from token {token:?}")]
924    DymParse {
925        field: &'static str,
926        line: usize,
927        token: String,
928    },
929
930    #[error("invalid FEFF .dym value for {field}: {message}")]
931    InvalidDym {
932        field: &'static str,
933        message: String,
934    },
935
936    #[error("FEFF .dym input has {count} trailing token(s)")]
937    DymTrailingTokens { count: usize },
938
939    #[error("missing grid.inp field {field}")]
940    GridInpMissing { field: &'static str },
941
942    #[error("could not parse grid.inp field {field} on line {line} from token {token:?}")]
943    GridInpParse {
944        field: &'static str,
945        line: usize,
946        token: String,
947    },
948
949    #[error("grid.inp row on line {line} has {actual} token(s), expected {expected}")]
950    GridInpRowWidth {
951        line: usize,
952        actual: usize,
953        expected: usize,
954    },
955
956    #[error("invalid grid.inp value for {field}: {message}")]
957    InvalidGridInp {
958        field: &'static str,
959        message: String,
960    },
961
962    #[error("missing config.inp field {field} on line {line}")]
963    ConfigInpMissing { field: &'static str, line: usize },
964
965    #[error("could not parse config.inp field {field} on line {line} from token {token:?}")]
966    ConfigInpParse {
967        field: &'static str,
968        line: usize,
969        token: String,
970    },
971
972    #[error("config.inp row on line {line} has {actual} token(s), expected at least {expected}")]
973    ConfigInpRowWidth {
974        line: usize,
975        actual: usize,
976        expected: usize,
977    },
978
979    #[error("invalid config.inp value for {field}: {message}")]
980    InvalidConfigInp {
981        field: &'static str,
982        message: String,
983    },
984
985    #[error("missing spring.inp field {field}")]
986    SpringInpMissing { field: &'static str },
987
988    #[error("could not parse spring.inp field {field} on line {line} from token {token:?}")]
989    SpringInpParse {
990        field: &'static str,
991        line: usize,
992        token: String,
993    },
994
995    #[error("spring.inp row on line {line} has {actual} token(s), expected at least {expected}")]
996    SpringInpRowWidth {
997        line: usize,
998        actual: usize,
999        expected: usize,
1000    },
1001
1002    #[error("invalid spring.inp value for {field}: {message}")]
1003    InvalidSpringInp {
1004        field: &'static str,
1005        message: String,
1006    },
1007
1008    #[error("invalid PAD width {0}; expected at least 3")]
1009    InvalidPadWidth(usize),
1010
1011    #[error("PAD line uses marker {found:?}, expected {expected:?}")]
1012    PadMarker { expected: char, found: char },
1013
1014    #[error("PAD payload length {payload_len} is not a multiple of {unit_len}")]
1015    PadPayload { payload_len: usize, unit_len: usize },
1016
1017    #[error("PAD encoder produced out-of-range byte {value}")]
1018    PadByte { value: i32 },
1019
1020    #[error("PAD exponent index {index} does not fit in i32")]
1021    PadIndex { index: usize },
1022
1023    #[error("polarization vector norm {norm} is too small")]
1024    InvalidPolarizationVector { norm: f64 },
1025
1026    #[error("polarization vector is almost parallel to incidence vector; dot product {dot}")]
1027    InvalidPolarizationGeometry { dot: f64 },
1028
1029    #[error("PAD encoded bytes were not valid UTF-8: {source}")]
1030    PadUtf8 {
1031        #[source]
1032        source: std::string::FromUtf8Error,
1033    },
1034
1035    #[error("PAD payload chunk was not valid UTF-8: {source}")]
1036    PadChunkUtf8 {
1037        #[source]
1038        source: std::str::Utf8Error,
1039    },
1040}
1041
1042impl IoError {
1043    pub(crate) fn io(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
1044        Self::Io {
1045            path: path.into(),
1046            source,
1047        }
1048    }
1049}
1050
1051impl From<std::fmt::Error> for IoError {
1052    fn from(source: std::fmt::Error) -> Self {
1053        Self::Format { source }
1054    }
1055}