Skip to main content

rust_stdf/
stdf_error.rs

1//
2// stdf_error.rs
3// Author: noonchen - chennoon233@foxmail.com
4// Created Date: October 3rd 2022
5// -----
6// Last Modified: Mon Nov 14 2022
7// Modified By: noonchen
8// -----
9// Copyright (c) 2022 noonchen
10//
11
12use 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}