dendryform_parse/
error.rs1use std::fmt;
4
5#[derive(Debug)]
7#[non_exhaustive]
8pub enum ParseError {
9 Yaml(serde_yml::Error),
11 Json(serde_json::Error),
13 Io(std::io::Error),
15 Validation(dendryform_core::ValidationError),
17}
18
19impl fmt::Display for ParseError {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match self {
22 Self::Yaml(e) => write!(f, "YAML parse error: {e}"),
23 Self::Json(e) => write!(f, "JSON parse error: {e}"),
24 Self::Io(e) => write!(f, "I/O error: {e}"),
25 Self::Validation(e) => write!(f, "validation error: {e}"),
26 }
27 }
28}
29
30impl std::error::Error for ParseError {
31 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
32 match self {
33 Self::Yaml(e) => Some(e),
34 Self::Json(e) => Some(e),
35 Self::Io(e) => Some(e),
36 Self::Validation(e) => Some(e),
37 }
38 }
39}
40
41impl From<serde_yml::Error> for ParseError {
42 fn from(e: serde_yml::Error) -> Self {
43 Self::Yaml(e)
44 }
45}
46
47impl From<serde_json::Error> for ParseError {
48 fn from(e: serde_json::Error) -> Self {
49 Self::Json(e)
50 }
51}
52
53impl From<std::io::Error> for ParseError {
54 fn from(e: std::io::Error) -> Self {
55 Self::Io(e)
56 }
57}
58
59impl From<dendryform_core::ValidationError> for ParseError {
60 fn from(e: dendryform_core::ValidationError) -> Self {
61 Self::Validation(e)
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use dendryform_core::ValidationError;
69
70 #[test]
71 fn test_display_yaml() {
72 let yaml_err: Result<serde_yml::Value, _> = serde_yml::from_str("[invalid yaml {");
73 let err = ParseError::Yaml(yaml_err.unwrap_err());
74 let msg = format!("{err}");
75 assert!(msg.contains("YAML parse error"));
76 }
77
78 #[test]
79 fn test_display_json() {
80 let json_err: Result<serde_json::Value, _> = serde_json::from_str("{invalid json");
81 let err = ParseError::Json(json_err.unwrap_err());
82 let msg = format!("{err}");
83 assert!(msg.contains("JSON parse error"));
84 }
85
86 #[test]
87 fn test_display_io() {
88 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
89 let err = ParseError::Io(io_err);
90 let msg = format!("{err}");
91 assert!(msg.contains("I/O error"));
92 }
93
94 #[test]
95 fn test_display_validation() {
96 let inner = ValidationError::MissingField { field: "title" };
97 let err = ParseError::Validation(inner);
98 let msg = format!("{err}");
99 assert!(msg.contains("validation error"));
100 assert!(msg.contains("title"));
101 }
102
103 #[test]
104 fn test_source_yaml() {
105 let yaml_err: Result<serde_yml::Value, _> = serde_yml::from_str("[bad {");
106 let err = ParseError::Yaml(yaml_err.unwrap_err());
107 assert!(std::error::Error::source(&err).is_some());
108 }
109
110 #[test]
111 fn test_source_json() {
112 let json_err: Result<serde_json::Value, _> = serde_json::from_str("{bad");
113 let err = ParseError::Json(json_err.unwrap_err());
114 assert!(std::error::Error::source(&err).is_some());
115 }
116
117 #[test]
118 fn test_source_io() {
119 let io_err = std::io::Error::new(std::io::ErrorKind::Other, "test");
120 let err = ParseError::Io(io_err);
121 assert!(std::error::Error::source(&err).is_some());
122 }
123
124 #[test]
125 fn test_source_validation() {
126 let inner = ValidationError::MissingField { field: "id" };
127 let err = ParseError::Validation(inner);
128 assert!(std::error::Error::source(&err).is_some());
129 }
130
131 #[test]
132 fn test_from_yaml_error() {
133 let yaml_err: Result<serde_yml::Value, _> = serde_yml::from_str("[bad {");
134 let inner = yaml_err.unwrap_err();
135 let err: ParseError = inner.into();
136 assert!(matches!(err, ParseError::Yaml(_)));
137 }
138
139 #[test]
140 fn test_from_json_error() {
141 let json_err: Result<serde_json::Value, _> = serde_json::from_str("{bad");
142 let inner = json_err.unwrap_err();
143 let err: ParseError = inner.into();
144 assert!(matches!(err, ParseError::Json(_)));
145 }
146
147 #[test]
148 fn test_from_io_error() {
149 let inner = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "denied");
150 let err: ParseError = inner.into();
151 assert!(matches!(err, ParseError::Io(_)));
152 }
153
154 #[test]
155 fn test_from_validation_error() {
156 let inner = ValidationError::EmptyTier { id: "t".to_owned() };
157 let err: ParseError = inner.into();
158 assert!(matches!(err, ParseError::Validation(_)));
159 }
160
161 #[test]
162 fn test_debug_format() {
163 let err = ParseError::Validation(ValidationError::MissingField { field: "id" });
164 let debug = format!("{err:?}");
165 assert!(debug.contains("Validation"));
166 }
167}