toasty_core/error/
validation.rs

1use super::Error;
2
3/// Error when a value fails validation constraints.
4#[derive(Debug)]
5pub(super) struct ValidationFailed {
6    kind: ValidationFailedKind,
7}
8
9#[derive(Debug)]
10pub(super) enum ValidationFailedKind {
11    /// String length constraint violation
12    Length {
13        value_len: usize,
14        min: Option<usize>,
15        max: Option<usize>,
16    },
17    /// General validation failure with message
18    Message { message: Box<str> },
19}
20
21impl std::error::Error for ValidationFailed {}
22
23impl core::fmt::Display for ValidationFailed {
24    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
25        match &self.kind {
26            ValidationFailedKind::Length {
27                value_len,
28                min,
29                max,
30            } => {
31                // If min and max are the same, show exact length requirement
32                if min == max && min.is_some() {
33                    let expected = min.unwrap();
34                    return write!(
35                        f,
36                        "value length {} does not match required length {}",
37                        value_len, expected
38                    );
39                }
40
41                // Check which constraint was violated
42                let too_short = min.is_some_and(|m| *value_len < m);
43                let too_long = max.is_some_and(|m| *value_len > m);
44
45                if too_short {
46                    write!(
47                        f,
48                        "value length {} is too short (minimum: {})",
49                        value_len,
50                        min.unwrap()
51                    )
52                } else if too_long {
53                    write!(
54                        f,
55                        "value length {} is too long (maximum: {})",
56                        value_len,
57                        max.unwrap()
58                    )
59                } else {
60                    f.write_str("length constraint violation")
61                }
62            }
63            ValidationFailedKind::Message { message } => {
64                write!(f, "validation failed: {}", message)
65            }
66        }
67    }
68}
69
70impl Error {
71    /// Creates a general validation error.
72    pub fn validation_failed(message: impl Into<String>) -> Error {
73        Error::from(super::ErrorKind::ValidationFailed(ValidationFailed {
74            kind: ValidationFailedKind::Message {
75                message: message.into().into(),
76            },
77        }))
78    }
79
80    /// Creates a validation error for a length constraint violation.
81    ///
82    /// This is used when a string value violates minimum or maximum length constraints.
83    pub fn validation_length(value_len: usize, min: Option<usize>, max: Option<usize>) -> Error {
84        Error::from(super::ErrorKind::ValidationFailed(ValidationFailed {
85            kind: ValidationFailedKind::Length {
86                value_len,
87                min,
88                max,
89            },
90        }))
91    }
92
93    /// Returns `true` if this error is a validation error.
94    pub fn is_validation(&self) -> bool {
95        matches!(self.kind(), super::ErrorKind::ValidationFailed(_))
96    }
97}