todo_file/errors/
io.rs

1use std::{io, path::PathBuf};
2
3use thiserror::Error;
4
5use crate::errors::ParseError;
6
7/// The cause of a `FileRead` error
8#[derive(Error, Debug)]
9#[non_exhaustive]
10#[allow(variant_size_differences)]
11pub enum FileReadErrorCause {
12	/// Caused by an io error
13	#[error(transparent)]
14	IoError(#[from] io::Error),
15	/// Caused by a parse error
16	#[error(transparent)]
17	ParseError(#[from] ParseError),
18}
19
20impl PartialEq for FileReadErrorCause {
21	#[inline]
22	#[allow(clippy::pattern_type_mismatch)]
23	fn eq(&self, other: &Self) -> bool {
24		match (self, other) {
25			(Self::IoError(self_err), Self::IoError(other_err)) => self_err.kind() == other_err.kind(),
26			(Self::ParseError(self_err), Self::ParseError(other_err)) => self_err == other_err,
27			_ => false,
28		}
29	}
30}
31
32/// IO baser errors
33#[derive(Error, Debug, PartialEq)]
34#[non_exhaustive]
35pub enum IoError {
36	/// The file could not be read
37	#[error("Unable to read file `{file}`")]
38	FileRead {
39		/// The file path that failed to read
40		file: PathBuf,
41		/// The reason for the read error
42		cause: FileReadErrorCause,
43	},
44}
45
46#[cfg(test)]
47mod test {
48	use super::*;
49
50	#[test]
51	fn partial_eq_file_read_error_cause_different_cause() {
52		assert_ne!(
53			FileReadErrorCause::IoError(io::Error::from(io::ErrorKind::Other)),
54			FileReadErrorCause::ParseError(ParseError::InvalidAction(String::from("action")))
55		);
56	}
57
58	#[test]
59	fn partial_eq_file_read_error_cause_io_error_same_kind() {
60		assert_eq!(
61			FileReadErrorCause::IoError(io::Error::from(io::ErrorKind::Other)),
62			FileReadErrorCause::IoError(io::Error::from(io::ErrorKind::Other))
63		);
64	}
65
66	#[test]
67	fn partial_eq_file_read_error_cause_io_error_different_kind() {
68		assert_ne!(
69			FileReadErrorCause::IoError(io::Error::from(io::ErrorKind::Other)),
70			FileReadErrorCause::IoError(io::Error::from(io::ErrorKind::NotFound))
71		);
72	}
73
74	#[test]
75	fn partial_eq_file_read_error_cause_different_parse_error() {
76		assert_ne!(
77			FileReadErrorCause::ParseError(ParseError::InvalidAction(String::from("action"))),
78			FileReadErrorCause::ParseError(ParseError::InvalidLine(String::from("line"))),
79		);
80	}
81
82	#[test]
83	fn partial_eq_file_read_error_cause_same_parse_error() {
84		assert_eq!(
85			FileReadErrorCause::ParseError(ParseError::InvalidAction(String::from("action"))),
86			FileReadErrorCause::ParseError(ParseError::InvalidAction(String::from("action"))),
87		);
88	}
89}