Skip to main content

polyspec_crudui_validator/validate/
errors.rs

1//! Validation failures that produce no validation result.
2
3use std::fmt;
4
5use crate::compose::ComposeLoadError;
6
7/// Submitted form data whose shape does not match the specification.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct FormInputError {
10    /// The rule and the data path.
11    pub message: String,
12}
13
14impl FormInputError {
15    /// Stable machine-readable code shared with the form runtime.
16    pub const CODE: &'static str = "INVALID_FORM_INPUT";
17
18    pub(crate) fn new(message: impl Into<String>) -> Self {
19        FormInputError {
20            message: message.into(),
21        }
22    }
23}
24
25impl fmt::Display for FormInputError {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.write_str(&self.message)
28    }
29}
30
31impl std::error::Error for FormInputError {}
32
33/// A validation run that produced no validation result.
34#[derive(Debug, Clone, PartialEq)]
35pub enum ValidateError {
36    /// The specification could not be composed.
37    Load(ComposeLoadError),
38    /// Submitted data has the wrong shape.
39    Input(FormInputError),
40}
41
42impl ValidateError {
43    /// Stable machine-readable code.
44    pub fn code(&self) -> &str {
45        match self {
46            ValidateError::Load(error) => error.code.as_str(),
47            ValidateError::Input(_) => FormInputError::CODE,
48        }
49    }
50
51    /// Failure message without the code.
52    pub fn message(&self) -> &str {
53        match self {
54            ValidateError::Load(error) => &error.message,
55            ValidateError::Input(error) => &error.message,
56        }
57    }
58
59    /// Load-failure trace joined with `.` (a composition trace or a field's
60    /// declaration path); empty for an input failure.
61    pub fn at(&self) -> String {
62        match self {
63            ValidateError::Load(error) => error.trace.join("."),
64            ValidateError::Input(_) => String::new(),
65        }
66    }
67}
68
69impl fmt::Display for ValidateError {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        match self {
72            ValidateError::Load(error) => error.fmt(f),
73            ValidateError::Input(error) => error.fmt(f),
74        }
75    }
76}
77
78impl std::error::Error for ValidateError {}
79
80impl From<ComposeLoadError> for ValidateError {
81    fn from(error: ComposeLoadError) -> Self {
82        ValidateError::Load(error)
83    }
84}
85
86impl From<FormInputError> for ValidateError {
87    fn from(error: FormInputError) -> Self {
88        ValidateError::Input(error)
89    }
90}