Skip to main content

easyofd_reader/
bad_ofd_exception.rs

1//! 错误 OFD 文件结构和文档格式异常。
2//!
3//! 对应 Java: org.ofdrw.reader.BadOFDException
4
5use thiserror::Error;
6
7/// 错误 OFD 文件结构和文档格式异常。
8///
9/// 当 OFD 文档结构损坏、格式不符合 GB/T 33190 规范,
10/// 或解析过程中遇到不可恢复的错误时抛出。
11///
12/// 对应 Java: `org.ofdrw.reader.BadOFDException`
13#[derive(Debug, Error)]
14#[non_exhaustive]
15pub enum BadOfdException {
16    /// 文档结构损坏。
17    #[error("错误OFD结构和文件格式: {message}")]
18    CorruptedStructure {
19        /// 错误描述。
20        message: String,
21    },
22
23    /// 文档解析失败。
24    #[error("OFD解析失败: {message}")]
25    ParseFailed {
26        /// 错误描述。
27        message: String,
28    },
29
30    /// 文件不存在。
31    #[error("文件不存在: {path}")]
32    FileNotFound {
33        /// 文件路径。
34        path: String,
35    },
36
37    /// 底层 IO 或 ZIP 错误。
38    #[error(transparent)]
39    Other(#[from] easyofd_core::OfdError),
40}
41
42impl BadOfdException {
43    /// 创建文档结构损坏异常。
44    pub fn corrupted(message: impl Into<String>) -> Self {
45        Self::CorruptedStructure {
46            message: message.into(),
47        }
48    }
49
50    /// 创建解析失败异常。
51    pub fn parse_failed(message: impl Into<String>) -> Self {
52        Self::ParseFailed {
53            message: message.into(),
54        }
55    }
56
57    /// 创建文件不存在异常。
58    pub fn file_not_found(path: impl Into<String>) -> Self {
59        Self::FileNotFound { path: path.into() }
60    }
61}
62
63impl From<BadOfdException> for easyofd_core::OfdError {
64    fn from(e: BadOfdException) -> Self {
65        match e {
66            BadOfdException::CorruptedStructure { message }
67            | BadOfdException::ParseFailed { message } => {
68                easyofd_core::OfdError::InvalidDocument(message)
69            }
70            BadOfdException::FileNotFound { path } => easyofd_core::OfdError::Zip(path),
71            BadOfdException::Other(inner) => inner,
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn test_corrupted_structure() {
82        let e = BadOfdException::corrupted("missing DocRoot");
83        assert!(e.to_string().contains("missing DocRoot"));
84    }
85
86    #[test]
87    fn test_parse_failed() {
88        let e = BadOfdException::parse_failed("invalid XML");
89        assert!(e.to_string().contains("invalid XML"));
90    }
91
92    #[test]
93    fn test_file_not_found() {
94        let e = BadOfdException::file_not_found("/Doc_0/missing.xml");
95        assert!(e.to_string().contains("/Doc_0/missing.xml"));
96    }
97
98    #[test]
99    fn test_from_ofd_error() {
100        let ofd_err = easyofd_core::OfdError::Zip("bad zip".into());
101        let bad: BadOfdException = ofd_err.into();
102        assert!(matches!(bad, BadOfdException::Other(_)));
103    }
104
105    #[test]
106    fn test_into_ofd_error() {
107        let bad = BadOfdException::corrupted("test");
108        let ofd_err: easyofd_core::OfdError = bad.into();
109        assert!(matches!(
110            ofd_err,
111            easyofd_core::OfdError::InvalidDocument(_)
112        ));
113    }
114}