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)]
24#[repr(u8)]
25pub(crate) enum StdfErrorKind {
26 InvalidStdfFile = 1,
27 InvalidRecordType = 2,
28 Io = 3,
29 Eof = 4,
30 UnexpectedEof = 5,
31 NonAscii = 6,
32 InvalidAtdfFile = 7,
33 #[cfg(feature = "zipfile")]
34 Zip = 8,
35}
36
37impl StdfErrorKind {
38 pub(crate) fn from_u8(code: u8) -> Option<Self> {
39 Some(match code {
40 1 => Self::InvalidStdfFile,
41 2 => Self::InvalidRecordType,
42 3 => Self::Io,
43 4 => Self::Eof,
44 5 => Self::UnexpectedEof,
45 6 => Self::NonAscii,
46 7 => Self::InvalidAtdfFile,
47 #[cfg(feature = "zipfile")]
48 8 => Self::Zip,
49 _ => return None,
50 })
51 }
52}
53
54impl StdfError {
55 pub(crate) fn new(kind: StdfErrorKind, msg: impl Into<String>) -> Self {
56 Self {
57 code: kind as u8,
58 msg: msg.into(),
59 }
60 }
61
62 pub(crate) fn kind(&self) -> Option<StdfErrorKind> {
63 StdfErrorKind::from_u8(self.code)
64 }
65}
66
67impl fmt::Display for StdfError {
68 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69 let short_msg = match StdfErrorKind::from_u8(self.code) {
70 Some(StdfErrorKind::InvalidStdfFile) => "Invalid STDF File",
71 Some(StdfErrorKind::InvalidRecordType) => "Invalid Record Type",
72 Some(StdfErrorKind::Io) => "IO Error",
73 Some(StdfErrorKind::Eof) => "EOF",
74 Some(StdfErrorKind::UnexpectedEof) => "Unexpected EOF",
75 Some(StdfErrorKind::NonAscii) => "Non-ASCII Found",
76 Some(StdfErrorKind::InvalidAtdfFile) => "Invalid ATDF File",
77 #[cfg(feature = "zipfile")]
78 Some(StdfErrorKind::Zip) => "Zip related",
79 _ => "Other error",
80 };
81 write!(f, "{}, {}", short_msg, self.msg)
82 }
83}
84
85impl From<io::Error> for StdfError {
86 fn from(error: io::Error) -> Self {
87 match error.kind() {
88 ErrorKind::UnexpectedEof => {
89 StdfError::new(StdfErrorKind::Eof, String::from("End of file detected"))
90 }
91 _ => StdfError::new(StdfErrorKind::Io, format!("{}, {}", error.kind(), error)),
92 }
93 }
94}
95
96#[cfg(feature = "zipfile")]
97impl From<ZipError> for StdfError {
98 fn from(error: ZipError) -> Self {
99 match error {
100 ZipError::Io(err) => StdfError::new(StdfErrorKind::Io, err.to_string()),
101 _ => StdfError::new(StdfErrorKind::Zip, error.to_string()),
102 }
103 }
104}