Skip to main content

ferris_files/
errors.rs

1/// Error type representing various failures that can occur during search operations.
2///
3/// This enum encapsulates different types of errors that might occur during file analysis or
4/// directory traversal, including I/O errors, thread communication errors,
5/// and filepath-related errors.
6#[derive(Debug)]
7pub enum SearchError {
8    /// Represents underlying I/O errors from the standard library.
9    ///
10    /// This variant wraps [`std::io::Error`] and is commonly used for file system
11    /// operations that fail, such as reading directories or files.
12    IoError(std::io::Error),
13
14    /// Represents errors that occur when sending data between threads.
15    ///
16    /// Contains a string description of what went wrong during the send operation.
17    SendError(String),
18
19    /// Represents errors related to thread operation failures.
20    ///
21    /// Contains a string description of what went wrong with thread handling,
22    /// such as join handle errors or thread panic information.
23    ThreadError(String),
24
25    /// Represents errors related to invalid or problematic file paths.
26    ///
27    /// Contains a string description of what went wrong with the path,
28    /// such as invalid characters or path syntax errors.
29    PathError(String),
30}
31
32impl From<std::io::Error> for SearchError {
33    /// Converts a [`std::io::Error`] into a [`SearchError`].
34    ///
35    /// This implementation allows for easy conversion of standard I/O errors
36    /// into our custom error type using the `?` operator.
37    ///
38    /// # Examples
39    /// ```
40    /// use std::fs::File;
41    /// use ferris_files::errors::SearchError;
42    ///
43    /// fn read_file() -> Result<(), SearchError> {
44    ///     let _file = File::open("nonexistent.txt")?; // Will convert io::Error to SearchError
45    ///     Ok(())
46    /// }
47    /// assert!(matches!(read_file(), Err(SearchError)));
48    /// ```
49    fn from(err: std::io::Error) -> Self {
50        SearchError::IoError(err)
51    }
52}
53
54impl std::fmt::Display for SearchError {
55    /// Formats the error for display purposes.
56    ///
57    /// Provides a human-readable error message that includes both the error type
58    /// and its associated details.
59    ///
60    /// # Examples
61    /// ```
62    /// use ferris_files::errors::SearchError;
63    /// let err = SearchError::PathError("Invalid path character".to_string());
64    /// assert_eq!(format!("{}", err), "Path error: Invalid path character");
65    /// ```
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        match self {
68            SearchError::IoError(e) => write!(f, "IO error: {}", e),
69            SearchError::SendError(e) => write!(f, "Send error: {}", e),
70            SearchError::ThreadError(e) => write!(f, "Thread error: {}", e),
71            SearchError::PathError(e) => write!(f, "Path error: {}", e),
72        }
73    }
74}
75
76impl std::error::Error for SearchError {
77    /// Returns the lower-level source of this error, if any.
78    ///
79    /// Currently only returns a source for [`SearchError::IoError`], as it's the only
80    /// variant that wraps another error type implementing [`std::error::Error`].
81    ///
82    /// # Returns
83    /// - `Some(&std::io::Error)` for `IoError` variant
84    /// - `None` for all other variants
85    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
86        match self {
87            SearchError::IoError(e) => Some(e),
88            _ => None,
89        }
90    }
91}