feedparser_rs/
error.rs

1use thiserror::Error;
2
3/// Feed parsing errors
4#[derive(Error, Debug, Clone)]
5pub enum FeedError {
6    /// XML parsing error
7    #[error("XML parsing error: {0}")]
8    XmlError(String),
9
10    /// I/O error
11    #[error("IO error: {0}")]
12    IoError(String),
13
14    /// Invalid feed format
15    #[error("Invalid feed format: {0}")]
16    InvalidFormat(String),
17
18    /// Encoding error
19    #[error("Encoding error: {0}")]
20    EncodingError(String),
21
22    /// JSON parsing error
23    #[error("JSON parsing error: {0}")]
24    JsonError(String),
25
26    /// HTTP error
27    #[error("HTTP error: {message}")]
28    Http {
29        /// Error message
30        message: String,
31    },
32
33    /// URL parsing error
34    #[error("URL parsing error: {0}")]
35    UrlError(String),
36
37    /// Unknown error
38    #[error("Unknown error: {0}")]
39    Unknown(String),
40}
41
42/// Result type for feed parsing operations
43pub type Result<T> = std::result::Result<T, FeedError>;
44
45impl From<quick_xml::Error> for FeedError {
46    fn from(err: quick_xml::Error) -> Self {
47        Self::XmlError(err.to_string())
48    }
49}
50
51impl From<serde_json::Error> for FeedError {
52    fn from(err: serde_json::Error) -> Self {
53        Self::JsonError(err.to_string())
54    }
55}
56
57impl From<std::io::Error> for FeedError {
58    fn from(err: std::io::Error) -> Self {
59        Self::IoError(err.to_string())
60    }
61}
62
63impl From<url::ParseError> for FeedError {
64    fn from(err: url::ParseError) -> Self {
65        Self::UrlError(err.to_string())
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_error_display() {
75        let err = FeedError::XmlError("test".to_string());
76        assert_eq!(err.to_string(), "XML parsing error: test");
77    }
78
79    #[test]
80    fn test_error_from_io() {
81        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
82        let feed_err = FeedError::from(io_err);
83        assert!(matches!(feed_err, FeedError::IoError(_)));
84    }
85
86    #[test]
87    #[allow(clippy::unnecessary_wraps)]
88    fn test_result_type() {
89        fn get_result() -> Result<i32> {
90            Ok(42)
91        }
92        let result = get_result();
93        assert!(result.is_ok());
94        assert_eq!(result.expect("should be ok"), 42);
95
96        let error: Result<i32> = Err(FeedError::Unknown("test".to_string()));
97        assert!(error.is_err());
98    }
99}