1use std::fmt;
2use std::io;
3
4pub type Result<T> = std::result::Result<T, GitError>;
5
6#[derive(Debug, Clone)]
7pub enum GitError {
8 IoError(String),
9 CommandFailed(String),
10}
11
12impl fmt::Display for GitError {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 match self {
15 GitError::IoError(msg) => write!(f, "IO error: {}", msg),
16 GitError::CommandFailed(msg) => write!(f, "Git command failed: {}", msg),
17 }
18 }
19}
20
21impl std::error::Error for GitError {}
22
23impl From<io::Error> for GitError {
24 fn from(error: io::Error) -> Self {
25 GitError::IoError(error.to_string())
26 }
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32 use std::io;
33
34 #[test]
35 fn test_git_error_io_error_variant() {
36 let error = GitError::IoError("test io error".to_string());
37 match error {
38 GitError::IoError(msg) => assert_eq!(msg, "test io error"),
39 _ => panic!("Expected IoError variant"),
40 }
41 }
42
43 #[test]
44 fn test_git_error_command_failed_variant() {
45 let error = GitError::CommandFailed("test command failed".to_string());
46 match error {
47 GitError::CommandFailed(msg) => assert_eq!(msg, "test command failed"),
48 _ => panic!("Expected CommandFailed variant"),
49 }
50 }
51
52 #[test]
53 fn test_git_error_clone() {
54 let error1 = GitError::IoError("test error".to_string());
55 let error2 = error1.clone();
56
57 match (error1, error2) {
58 (GitError::IoError(msg1), GitError::IoError(msg2)) => assert_eq!(msg1, msg2),
59 _ => panic!("Clone failed or wrong variant"),
60 }
61 }
62
63 #[test]
64 fn test_git_error_debug() {
65 let io_error = GitError::IoError("io test".to_string());
66 let cmd_error = GitError::CommandFailed("cmd test".to_string());
67
68 let io_debug = format!("{:?}", io_error);
69 let cmd_debug = format!("{:?}", cmd_error);
70
71 assert!(io_debug.contains("IoError"));
72 assert!(io_debug.contains("io test"));
73 assert!(cmd_debug.contains("CommandFailed"));
74 assert!(cmd_debug.contains("cmd test"));
75 }
76
77 #[test]
78 fn test_from_io_error() {
79 let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
80 let git_err: GitError = io_err.into();
81
82 match git_err {
83 GitError::IoError(msg) => assert!(msg.contains("file not found")),
84 _ => panic!("Expected IoError variant from io::Error conversion"),
85 }
86 }
87
88 #[test]
89 fn test_from_io_error_different_kinds() {
90 let permission_err = io::Error::new(io::ErrorKind::PermissionDenied, "access denied");
91 let git_err: GitError = permission_err.into();
92
93 match git_err {
94 GitError::IoError(msg) => assert!(msg.contains("access denied")),
95 _ => panic!("Expected IoError variant"),
96 }
97 }
98
99 #[test]
100 fn test_result_type_alias() {
101 fn test_function() -> Result<String> {
102 Ok("success".to_string())
103 }
104
105 let result = test_function();
106 assert!(result.is_ok());
107 assert_eq!(result.unwrap(), "success");
108 }
109
110 #[test]
111 fn test_result_type_alias_error() {
112 fn test_function() -> Result<String> {
113 Err(GitError::CommandFailed("test error".to_string()))
114 }
115
116 let result = test_function();
117 assert!(result.is_err());
118 match result.unwrap_err() {
119 GitError::CommandFailed(msg) => assert_eq!(msg, "test error"),
120 _ => panic!("Expected CommandFailed variant"),
121 }
122 }
123}