1use thiserror::Error;
2
3#[derive(Debug, Clone, Error)]
4#[error("{path}: {message}")]
5pub struct ValidationError {
6 pub path: String,
7 pub message: String,
8}
9
10impl ValidationError {
11 pub fn new(path: impl Into<String>, message: impl Into<String>) -> Self {
12 Self { path: path.into(), message: message.into() }
13 }
14
15 pub fn root(message: impl Into<String>) -> Self {
16 Self { path: String::new(), message: message.into() }
17 }
18
19 pub fn at(mut self, field: &str) -> Self {
20 if self.path.is_empty() {
21 self.path = field.to_string();
22 } else if self.path.starts_with('[') {
23 self.path = format!("{field}{}", self.path);
24 } else {
25 self.path = format!("{field}.{}", self.path);
26 }
27 self
28 }
29
30 pub fn at_index(mut self, idx: usize) -> Self {
31 self.path = format!(
32 "[{idx}]{}",
33 if self.path.is_empty() {
34 String::new()
35 } else if self.path.starts_with('[') {
36 self.path.clone()
37 } else {
38 format!(".{}", self.path)
39 }
40 );
41 self
42 }
43}