1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum Error {
8 #[error("Invalid record: {0}")]
9 InvalidRecord(String),
10
11 #[error("JSON parse error on line {line}: {message}")]
12 JsonParse { line: usize, message: String },
13
14 #[error("CSV parse error: {0}")]
15 CsvParse(String),
16
17 #[error("IO error: {0}")]
18 Io(#[from] std::io::Error),
19
20 #[error("Schema file error: {0}")]
21 SchemaFile(String),
22}
23
24pub type Result<T> = std::result::Result<T, Error>;
26
27#[derive(Debug, Clone)]
29pub struct ErrorLog {
30 pub line_number: usize,
32 pub msg: String,
34}
35
36impl std::fmt::Display for ErrorLog {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 write!(f, "Line {}: {}", self.line_number, self.msg)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_error_log_display() {
48 let error = ErrorLog {
49 line_number: 42,
50 msg: "test error".to_string(),
51 };
52 assert_eq!(format!("{}", error), "Line 42: test error");
53 }
54
55 #[test]
56 fn test_error_log_display_line_one() {
57 let error = ErrorLog {
58 line_number: 1,
59 msg: "first line error".to_string(),
60 };
61 assert_eq!(format!("{}", error), "Line 1: first line error");
62 }
63
64 #[test]
65 fn test_error_log_display_large_line_number() {
66 let error = ErrorLog {
67 line_number: 1_000_000,
68 msg: "large line".to_string(),
69 };
70 assert_eq!(format!("{}", error), "Line 1000000: large line");
71 }
72
73 #[test]
74 fn test_error_log_display_empty_message() {
75 let error = ErrorLog {
76 line_number: 10,
77 msg: String::new(),
78 };
79 assert_eq!(format!("{}", error), "Line 10: ");
80 }
81
82 #[test]
83 fn test_error_invalid_record_display() {
84 let error = Error::InvalidRecord("not an object".to_string());
85 assert_eq!(format!("{}", error), "Invalid record: not an object");
86 }
87
88 #[test]
89 fn test_error_json_parse_display() {
90 let error = Error::JsonParse {
91 line: 5,
92 message: "unexpected token".to_string(),
93 };
94 assert_eq!(
95 format!("{}", error),
96 "JSON parse error on line 5: unexpected token"
97 );
98 }
99
100 #[test]
101 fn test_error_csv_parse_display() {
102 let error = Error::CsvParse("invalid CSV".to_string());
103 assert_eq!(format!("{}", error), "CSV parse error: invalid CSV");
104 }
105
106 #[test]
107 fn test_error_io_display() {
108 let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
109 let error = Error::Io(io_error);
110 assert!(format!("{}", error).contains("IO error"));
111 assert!(format!("{}", error).contains("file not found"));
112 }
113
114 #[test]
115 fn test_error_schema_file_display() {
116 let error = Error::SchemaFile("invalid schema format".to_string());
117 assert_eq!(
118 format!("{}", error),
119 "Schema file error: invalid schema format"
120 );
121 }
122
123 #[test]
124 fn test_error_from_io_error() {
125 let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "access denied");
126 let error: Error = io_error.into();
127 assert!(matches!(error, Error::Io(_)));
128 }
129}