yesser_todo_errors/
db_error.rs1use thiserror::Error;
2
3#[derive(Debug, Error)]
4pub enum DatabaseError {
5 #[error("A JSON deserialization error occured: {0}")]
6 JsonError(serde_json::Error),
7
8 #[error("An error occurred while writing to config file or directory: {0}")]
9 IOError(std::io::Error),
10
11 #[error("Could not get user config directory location")]
12 UserDirsError,
13}
14
15impl From<serde_json::Error> for DatabaseError {
16 fn from(value: serde_json::Error) -> Self {
27 Self::JsonError(value)
28 }
29}
30
31impl From<std::io::Error> for DatabaseError {
32 fn from(err: std::io::Error) -> Self {
46 Self::IOError(err)
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53 use std::io::ErrorKind;
54
55 #[test]
56 fn test_from_json_error() {
57 let json_err = serde_json::from_str::<serde_json::Value>("not valid json").unwrap_err();
58 let db_err = DatabaseError::from(json_err);
59 assert!(matches!(db_err, DatabaseError::JsonError(_)));
60 }
61
62 #[test]
63 fn test_from_io_error() {
64 let io_err = std::io::Error::new(ErrorKind::NotFound, "file not found");
65 let db_err = DatabaseError::from(io_err);
66 match db_err {
67 DatabaseError::IOError(e) => {
68 assert_eq!(e.kind(), ErrorKind::NotFound);
69 assert_eq!(e.to_string(), "file not found");
70 }
71 _ => panic!("expected IOError"),
72 }
73 }
74
75 #[test]
76 fn test_json_error_display() {
77 let json_err = serde_json::from_str::<serde_json::Value>("{bad json}").unwrap_err();
78 let db_err = DatabaseError::JsonError(json_err);
79 let display = format!("{}", db_err);
80 assert!(display.contains("JSON deserialization error occured"));
81 }
82
83 #[test]
84 fn test_io_error_display() {
85 let io_err = std::io::Error::new(ErrorKind::PermissionDenied, "access denied");
86 let db_err = DatabaseError::IOError(io_err);
87 let display = format!("{}", db_err);
88 assert!(display.contains("error occurred while writing to config file or directory"));
89 assert!(display.contains("access denied"));
90 }
91
92 #[test]
93 fn test_user_dirs_error_display() {
94 let db_err = DatabaseError::UserDirsError;
95 let display = format!("{}", db_err);
96 assert_eq!(display, "Could not get user config directory location");
97 }
98
99 #[test]
100 fn test_database_error_is_error_trait() {
101 fn assert_error<T: std::error::Error>() {}
102 assert_error::<DatabaseError>();
103 }
104
105 #[test]
106 fn test_database_error_debug() {
107 let db_err = DatabaseError::UserDirsError;
108 let debug_str = format!("{:?}", db_err);
109 assert!(debug_str.contains("UserDirsError"));
110 }
111
112 #[test]
113 fn test_from_various_io_error_kinds() {
114 let error_kinds = vec![
115 ErrorKind::NotFound,
116 ErrorKind::PermissionDenied,
117 ErrorKind::AlreadyExists,
118 ErrorKind::WouldBlock,
119 ];
120
121 for kind in error_kinds {
122 let io_err = std::io::Error::new(kind, "test error");
123 let db_err = DatabaseError::from(io_err);
124 match db_err {
125 DatabaseError::IOError(e) => assert_eq!(e.kind(), kind),
126 _ => panic!("expected IOError for kind {:?}", kind),
127 }
128 }
129 }
130
131 #[test]
132 fn test_json_error_from_invalid_types() {
133 let json_err = serde_json::from_str::<Vec<String>>("{\"not\": \"an array\"}").unwrap_err();
134 let db_err = DatabaseError::from(json_err);
135 assert!(matches!(db_err, DatabaseError::JsonError(_)));
136 }
137}