1use std::fmt;
13use std::io::{self, ErrorKind};
14#[cfg(feature = "zipfile")]
15use zip::result::ZipError;
16
17#[derive(Debug)]
18pub struct StdfError {
19 pub code: u8,
20 pub msg: String,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27#[repr(u8)]
28#[non_exhaustive]
29pub enum StdfErrorKind {
30 InvalidStdfFile = 1,
31 InvalidRecordType = 2,
32 Io = 3,
33 Eof = 4,
34 UnexpectedEof = 5,
35 NonAscii = 6,
36 InvalidAtdfFile = 7,
37 #[cfg(feature = "zipfile")]
38 Zip = 8,
39 InvalidLength = 9,
40 CountMismatch = 10,
41 WidthMismatch = 11,
42 InvalidOptionalOrder = 12,
43 InvalidValue = 13,
44 RecordTooLarge = 14,
45 ByteOrderMismatch = 15,
46 Unknown = 255,
47}
48
49impl StdfErrorKind {
50 pub(crate) fn from_u8(code: u8) -> Self {
51 match code {
52 1 => Self::InvalidStdfFile,
53 2 => Self::InvalidRecordType,
54 3 => Self::Io,
55 4 => Self::Eof,
56 5 => Self::UnexpectedEof,
57 6 => Self::NonAscii,
58 7 => Self::InvalidAtdfFile,
59 #[cfg(feature = "zipfile")]
60 8 => Self::Zip,
61 9 => Self::InvalidLength,
62 10 => Self::CountMismatch,
63 11 => Self::WidthMismatch,
64 12 => Self::InvalidOptionalOrder,
65 13 => Self::InvalidValue,
66 14 => Self::RecordTooLarge,
67 15 => Self::ByteOrderMismatch,
68 _ => Self::Unknown,
69 }
70 }
71}
72
73impl StdfError {
74 pub(crate) fn new(kind: StdfErrorKind, msg: impl Into<String>) -> Self {
75 Self {
76 code: kind as u8,
77 msg: msg.into(),
78 }
79 }
80
81 pub fn kind(&self) -> StdfErrorKind {
84 StdfErrorKind::from_u8(self.code)
85 }
86}
87
88impl fmt::Display for StdfError {
89 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90 let short_msg = match StdfErrorKind::from_u8(self.code) {
91 StdfErrorKind::InvalidStdfFile => "Invalid STDF File",
92 StdfErrorKind::InvalidRecordType => "Invalid Record Type",
93 StdfErrorKind::Io => "IO Error",
94 StdfErrorKind::Eof => "EOF",
95 StdfErrorKind::UnexpectedEof => "Unexpected EOF",
96 StdfErrorKind::NonAscii => "Non-ASCII Found",
97 StdfErrorKind::InvalidAtdfFile => "Invalid ATDF File",
98 #[cfg(feature = "zipfile")]
99 StdfErrorKind::Zip => "Zip related",
100 StdfErrorKind::InvalidLength => "Invalid Length",
101 StdfErrorKind::CountMismatch => "Field Count Mismatch",
102 StdfErrorKind::WidthMismatch => "Field Width Mismatch",
103 StdfErrorKind::InvalidOptionalOrder => "Invalid Optional Field Order",
104 StdfErrorKind::InvalidValue => "Invalid Value",
105 StdfErrorKind::RecordTooLarge => "Record Too Large",
106 StdfErrorKind::ByteOrderMismatch => "Byte Order Mismatch",
107 StdfErrorKind::Unknown => "Unknown error",
108 };
109 write!(f, "{}, {}", short_msg, self.msg)
110 }
111}
112
113impl From<io::Error> for StdfError {
114 fn from(error: io::Error) -> Self {
115 match error.kind() {
116 ErrorKind::UnexpectedEof => {
117 StdfError::new(StdfErrorKind::Eof, String::from("End of file detected"))
118 }
119 _ => StdfError::new(StdfErrorKind::Io, format!("{}, {}", error.kind(), error)),
120 }
121 }
122}
123
124#[cfg(feature = "zipfile")]
125impl From<ZipError> for StdfError {
126 fn from(error: ZipError) -> Self {
127 match error {
128 ZipError::Io(err) => StdfError::new(StdfErrorKind::Io, err.to_string()),
129 _ => StdfError::new(StdfErrorKind::Zip, error.to_string()),
130 }
131 }
132}