1#[derive(Debug, Clone, PartialEq, Eq)]
2pub enum ErrorCode {
3 InvalidVersion,
4 MissingInputFormat,
5 InvalidInputFormat,
6 MissingCsvSection,
7 MissingJsonSection,
8 InvalidDelimiterLength,
9 MissingCsvColumns,
10
11 MissingTarget,
12 DuplicateTarget,
13 SourceValueExprExclusive,
14 MissingMappingValue,
15 InvalidWhenType,
16
17 InvalidRefNamespace,
18 ForwardOutReference,
19 UnknownOp,
20 InvalidArgs,
21 InvalidExprShape,
22 InvalidPath,
23
24 InvalidTypeName,
25
26 UndefinedVariable,
28 InvalidItemRef,
29 InvalidAccRef,
30 CyclicDependency,
31 EmptyPipe,
32 InvalidPipeStep,
33
34 MissingMappings,
36 StepsMappingExclusive,
37 InvalidStep,
38 InvalidFinalize,
39}
40
41impl ErrorCode {
42 pub fn as_str(&self) -> &'static str {
43 match self {
44 ErrorCode::InvalidVersion => "InvalidVersion",
45 ErrorCode::MissingInputFormat => "MissingInputFormat",
46 ErrorCode::InvalidInputFormat => "InvalidInputFormat",
47 ErrorCode::MissingCsvSection => "MissingCsvSection",
48 ErrorCode::MissingJsonSection => "MissingJsonSection",
49 ErrorCode::InvalidDelimiterLength => "InvalidDelimiterLength",
50 ErrorCode::MissingCsvColumns => "MissingCsvColumns",
51 ErrorCode::MissingTarget => "MissingTarget",
52 ErrorCode::DuplicateTarget => "DuplicateTarget",
53 ErrorCode::SourceValueExprExclusive => "SourceValueExprExclusive",
54 ErrorCode::MissingMappingValue => "MissingMappingValue",
55 ErrorCode::InvalidWhenType => "InvalidWhenType",
56 ErrorCode::InvalidRefNamespace => "InvalidRefNamespace",
57 ErrorCode::ForwardOutReference => "ForwardOutReference",
58 ErrorCode::UnknownOp => "UnknownOp",
59 ErrorCode::InvalidArgs => "InvalidArgs",
60 ErrorCode::InvalidExprShape => "InvalidExprShape",
61 ErrorCode::InvalidPath => "InvalidPath",
62 ErrorCode::InvalidTypeName => "InvalidTypeName",
63 ErrorCode::UndefinedVariable => "UndefinedVariable",
64 ErrorCode::InvalidItemRef => "InvalidItemRef",
65 ErrorCode::InvalidAccRef => "InvalidAccRef",
66 ErrorCode::CyclicDependency => "CyclicDependency",
67 ErrorCode::EmptyPipe => "EmptyPipe",
68 ErrorCode::InvalidPipeStep => "InvalidPipeStep",
69 ErrorCode::MissingMappings => "MissingMappings",
70 ErrorCode::StepsMappingExclusive => "StepsMappingExclusive",
71 ErrorCode::InvalidStep => "InvalidStep",
72 ErrorCode::InvalidFinalize => "InvalidFinalize",
73 }
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct YamlLocation {
79 pub line: usize,
80 pub column: usize,
81}
82
83#[derive(Debug, Clone, PartialEq, Eq)]
84pub struct RuleError {
85 pub code: ErrorCode,
86 pub message: String,
87 pub location: Option<YamlLocation>,
88 pub path: Option<String>,
89}
90
91impl RuleError {
92 pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
93 Self {
94 code,
95 message: message.into(),
96 location: None,
97 path: None,
98 }
99 }
100
101 pub fn with_path(mut self, path: impl Into<String>) -> Self {
102 self.path = Some(path.into());
103 self
104 }
105
106 pub fn with_location(mut self, line: usize, column: usize) -> Self {
107 self.location = Some(YamlLocation { line, column });
108 self
109 }
110}
111
112pub type ValidationResult = Result<(), Vec<RuleError>>;
113
114#[derive(Debug, Clone, PartialEq, Eq)]
115pub enum TransformErrorKind {
116 InvalidInput,
117 InvalidRecordsPath,
118 InvalidRef,
119 InvalidTarget,
120 MissingRequired,
121 TypeCastFailed,
122 ExprError,
123 AssertionFailed,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct TransformWarning {
128 pub kind: TransformErrorKind,
129 pub message: String,
130 pub path: Option<String>,
131}
132
133impl TransformWarning {
134 pub fn new(kind: TransformErrorKind, message: impl Into<String>) -> Self {
135 Self {
136 kind,
137 message: message.into(),
138 path: None,
139 }
140 }
141
142 pub fn with_path(mut self, path: impl Into<String>) -> Self {
143 self.path = Some(path.into());
144 self
145 }
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct TransformError {
150 pub kind: TransformErrorKind,
151 pub message: String,
152 pub path: Option<String>,
153}
154
155impl TransformError {
156 pub fn new(kind: TransformErrorKind, message: impl Into<String>) -> Self {
157 Self {
158 kind,
159 message: message.into(),
160 path: None,
161 }
162 }
163
164 pub fn with_path(mut self, path: impl Into<String>) -> Self {
165 self.path = Some(path.into());
166 self
167 }
168}
169
170impl std::fmt::Display for TransformError {
171 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172 if let Some(path) = &self.path {
173 write!(f, "{} (path: {})", self.message, path)
174 } else {
175 write!(f, "{}", self.message)
176 }
177 }
178}
179
180impl std::error::Error for TransformError {}
181
182impl From<TransformError> for TransformWarning {
183 fn from(err: TransformError) -> Self {
184 let mut warning = TransformWarning::new(err.kind, err.message);
185 if let Some(path) = err.path {
186 warning = warning.with_path(path);
187 }
188 warning
189 }
190}
191
192impl From<csv::Error> for TransformError {
193 fn from(err: csv::Error) -> Self {
194 TransformError::new(
195 TransformErrorKind::InvalidInput,
196 format!("csv error: {}", err),
197 )
198 }
199}
200
201impl From<serde_json::Error> for TransformError {
202 fn from(err: serde_json::Error) -> Self {
203 TransformError::new(
204 TransformErrorKind::InvalidInput,
205 format!("json error: {}", err),
206 )
207 }
208}