tauri_typegen/
error.rs

1use serde::{ser::Serializer, Serialize};
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7    #[error(transparent)]
8    Io(#[from] std::io::Error),
9
10    #[error("Command analysis failed: {0}")]
11    CommandAnalysis(String),
12
13    #[error("Code generation failed: {0}")]
14    CodeGeneration(String),
15
16    #[error("Invalid project path: {0}")]
17    InvalidProjectPath(String),
18}
19
20impl Serialize for Error {
21    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
22    where
23        S: Serializer,
24    {
25        serializer.serialize_str(self.to_string().as_ref())
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32    use std::io;
33
34    mod error_variants {
35        use super::*;
36
37        #[test]
38        fn test_io_error_creation() {
39            let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
40            let err = Error::from(io_err);
41            assert!(matches!(err, Error::Io(_)));
42            assert!(err.to_string().contains("file not found"));
43        }
44
45        #[test]
46        fn test_command_analysis_error() {
47            let err = Error::CommandAnalysis("failed to parse command".to_string());
48            assert!(matches!(err, Error::CommandAnalysis(_)));
49            assert_eq!(
50                err.to_string(),
51                "Command analysis failed: failed to parse command"
52            );
53        }
54
55        #[test]
56        fn test_code_generation_error() {
57            let err = Error::CodeGeneration("template rendering failed".to_string());
58            assert!(matches!(err, Error::CodeGeneration(_)));
59            assert_eq!(
60                err.to_string(),
61                "Code generation failed: template rendering failed"
62            );
63        }
64
65        #[test]
66        fn test_invalid_project_path_error() {
67            let err = Error::InvalidProjectPath("/invalid/path".to_string());
68            assert!(matches!(err, Error::InvalidProjectPath(_)));
69            assert_eq!(err.to_string(), "Invalid project path: /invalid/path");
70        }
71    }
72
73    mod error_display {
74        use super::*;
75
76        #[test]
77        fn test_command_analysis_display() {
78            let err = Error::CommandAnalysis("test error".to_string());
79            let display = format!("{}", err);
80            assert!(display.contains("Command analysis failed"));
81            assert!(display.contains("test error"));
82        }
83
84        #[test]
85        fn test_code_generation_display() {
86            let err = Error::CodeGeneration("test error".to_string());
87            let display = format!("{}", err);
88            assert!(display.contains("Code generation failed"));
89            assert!(display.contains("test error"));
90        }
91
92        #[test]
93        fn test_invalid_project_path_display() {
94            let err = Error::InvalidProjectPath("test path".to_string());
95            let display = format!("{}", err);
96            assert!(display.contains("Invalid project path"));
97            assert!(display.contains("test path"));
98        }
99
100        #[test]
101        fn test_debug_format() {
102            let err = Error::CommandAnalysis("test".to_string());
103            let debug = format!("{:?}", err);
104            assert!(debug.contains("CommandAnalysis"));
105        }
106    }
107
108    mod serialization {
109        use super::*;
110
111        #[test]
112        fn test_serialize_command_analysis_error() {
113            let err = Error::CommandAnalysis("test error".to_string());
114            let serialized = serde_json::to_string(&err).unwrap();
115            assert!(serialized.contains("Command analysis failed"));
116            assert!(serialized.contains("test error"));
117        }
118
119        #[test]
120        fn test_serialize_code_generation_error() {
121            let err = Error::CodeGeneration("generation failed".to_string());
122            let serialized = serde_json::to_string(&err).unwrap();
123            assert!(serialized.contains("Code generation failed"));
124            assert!(serialized.contains("generation failed"));
125        }
126
127        #[test]
128        fn test_serialize_invalid_project_path_error() {
129            let err = Error::InvalidProjectPath("/bad/path".to_string());
130            let serialized = serde_json::to_string(&err).unwrap();
131            assert!(serialized.contains("Invalid project path"));
132            assert!(serialized.contains("/bad/path"));
133        }
134
135        #[test]
136        fn test_serialize_io_error() {
137            let io_err = io::Error::new(io::ErrorKind::NotFound, "not found");
138            let err = Error::from(io_err);
139            let serialized = serde_json::to_string(&err).unwrap();
140            assert!(serialized.contains("not found"));
141        }
142    }
143
144    mod result_type {
145        use super::*;
146
147        #[test]
148        fn test_result_err() {
149            let result: Result<i32> = Err(Error::CommandAnalysis("test".to_string()));
150            assert!(result.is_err());
151        }
152
153        #[test]
154        fn test_result_with_question_mark() {
155            fn test_fn() -> Result<String> {
156                let err = Error::CommandAnalysis("test".to_string());
157                Err(err)?;
158                Ok("success".to_string())
159            }
160
161            let result = test_fn();
162            assert!(result.is_err());
163        }
164    }
165
166    mod from_conversions {
167        use super::*;
168
169        #[test]
170        fn test_from_io_error() {
171            let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "access denied");
172            let err: Error = io_err.into();
173            assert!(matches!(err, Error::Io(_)));
174        }
175
176        #[test]
177        fn test_io_error_kind_preserved() {
178            let io_err = io::Error::new(io::ErrorKind::NotFound, "missing");
179            let err = Error::from(io_err);
180            if let Error::Io(inner) = err {
181                assert_eq!(inner.kind(), io::ErrorKind::NotFound);
182            } else {
183                panic!("Expected Io error variant");
184            }
185        }
186    }
187}