1use std::fmt;
4
5#[derive(Debug)]
7pub enum ParseError {
8 Yaml(serde_yaml::Error),
10 Expression(crate::expression::ExpressionError),
12 Validation(String),
14 MissingField(String),
16 InvalidValue {
18 field: String,
20 message: String,
22 },
23}
24
25impl fmt::Display for ParseError {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Self::Yaml(e) => write!(f, "YAML error: {e}"),
29 Self::Expression(e) => write!(f, "Expression error: {e}"),
30 Self::Validation(msg) => write!(f, "Validation error: {msg}"),
31 Self::MissingField(field) => write!(f, "Missing required field: {field}"),
32 Self::InvalidValue { field, message } => {
33 write!(f, "Invalid value for '{field}': {message}")
34 }
35 }
36 }
37}
38
39impl std::error::Error for ParseError {
40 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41 match self {
42 Self::Yaml(e) => Some(e),
43 Self::Expression(e) => Some(e),
44 _ => None,
45 }
46 }
47}
48
49impl From<serde_yaml::Error> for ParseError {
50 fn from(e: serde_yaml::Error) -> Self {
51 Self::Yaml(e)
52 }
53}
54
55impl From<crate::expression::ExpressionError> for ParseError {
56 fn from(e: crate::expression::ExpressionError) -> Self {
57 Self::Expression(e)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use std::error::Error;
65
66 #[test]
67 fn test_parse_error_display() {
68 let err = ParseError::MissingField("name".to_string());
69 assert_eq!(err.to_string(), "Missing required field: name");
70
71 let err = ParseError::InvalidValue {
72 field: "columns".to_string(),
73 message: "must be positive".to_string(),
74 };
75 assert_eq!(
76 err.to_string(),
77 "Invalid value for 'columns': must be positive"
78 );
79
80 let err = ParseError::Validation("layout is required".to_string());
81 assert_eq!(err.to_string(), "Validation error: layout is required");
82 }
83
84 #[test]
85 fn test_parse_error_yaml_display() {
86 let yaml_err: serde_yaml::Error =
88 serde_yaml::from_str::<serde_yaml::Value>("{{").unwrap_err();
89 let err = ParseError::Yaml(yaml_err);
90 assert!(err.to_string().contains("YAML error"));
91 }
92
93 #[test]
94 fn test_parse_error_expression_display() {
95 use crate::expression::ExpressionError;
96 let expr_err = ExpressionError::UnknownTransform("missing".to_string());
97 let err = ParseError::Expression(expr_err);
98 assert!(err.to_string().contains("Expression error"));
99 }
100
101 #[test]
102 fn test_parse_error_from_yaml() {
103 let yaml_err: serde_yaml::Error =
104 serde_yaml::from_str::<serde_yaml::Value>("{{").unwrap_err();
105 let err: ParseError = yaml_err.into();
106 assert!(matches!(err, ParseError::Yaml(_)));
107 }
108
109 #[test]
110 fn test_parse_error_from_expression() {
111 use crate::expression::ExpressionError;
112 let expr_err = ExpressionError::EmptyExpression;
113 let err: ParseError = expr_err.into();
114 assert!(matches!(err, ParseError::Expression(_)));
115 }
116
117 #[test]
118 fn test_parse_error_source_yaml() {
119 let yaml_err: serde_yaml::Error =
120 serde_yaml::from_str::<serde_yaml::Value>("{{").unwrap_err();
121 let err = ParseError::Yaml(yaml_err);
122 assert!(err.source().is_some());
123 }
124
125 #[test]
126 fn test_parse_error_source_expression() {
127 use crate::expression::ExpressionError;
128 let expr_err = ExpressionError::InvalidArgument("bad arg".to_string());
129 let err = ParseError::Expression(expr_err);
130 assert!(err.source().is_some());
131 }
132
133 #[test]
134 fn test_parse_error_source_validation() {
135 let err = ParseError::Validation("test".to_string());
136 assert!(err.source().is_none());
137 }
138
139 #[test]
140 fn test_parse_error_source_missing_field() {
141 let err = ParseError::MissingField("test".to_string());
142 assert!(err.source().is_none());
143 }
144
145 #[test]
146 fn test_parse_error_source_invalid_value() {
147 let err = ParseError::InvalidValue {
148 field: "x".to_string(),
149 message: "y".to_string(),
150 };
151 assert!(err.source().is_none());
152 }
153}