reliakit_primitives/
error.rs1use core::fmt;
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8pub enum PrimitiveErrorKind {
9 Empty,
11 TooShort,
13 TooLong,
15 OutOfRange,
17 InvalidFormat,
19}
20
21#[non_exhaustive]
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum PrimitiveError {
25 Empty,
27 TooShort {
29 min: usize,
31 actual: usize,
33 },
34 TooLong {
36 max: usize,
38 actual: usize,
40 },
41 OutOfRange {
43 min: u128,
45 max: u128,
47 actual: u128,
49 },
50 Invalid {
52 message: &'static str,
54 },
55}
56
57pub type PrimitiveResult<T> = Result<T, PrimitiveError>;
59
60impl PrimitiveError {
61 pub const fn kind(&self) -> PrimitiveErrorKind {
63 match self {
64 Self::Empty => PrimitiveErrorKind::Empty,
65 Self::TooShort { .. } => PrimitiveErrorKind::TooShort,
66 Self::TooLong { .. } => PrimitiveErrorKind::TooLong,
67 Self::OutOfRange { .. } => PrimitiveErrorKind::OutOfRange,
68 Self::Invalid { .. } => PrimitiveErrorKind::InvalidFormat,
69 }
70 }
71}
72
73impl fmt::Display for PrimitiveError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match self {
76 Self::Empty => f.write_str("value must not be empty"),
77 Self::TooShort { min, actual } => {
78 write!(
79 f,
80 "value is too short: minimum is {min}, actual is {actual}"
81 )
82 }
83 Self::TooLong { max, actual } => {
84 write!(f, "value is too long: maximum is {max}, actual is {actual}")
85 }
86 Self::OutOfRange { min, max, actual } => {
87 write!(
88 f,
89 "value is out of range: expected {min}..={max}, actual is {actual}"
90 )
91 }
92 Self::Invalid { message } => write!(f, "invalid value: {message}"),
93 }
94 }
95}
96
97#[cfg(feature = "std")]
98impl std::error::Error for PrimitiveError {}
99
100#[cfg(test)]
101mod tests {
102 use super::{PrimitiveError, PrimitiveErrorKind};
103 use alloc::string::ToString;
104
105 #[test]
106 fn display_empty() {
107 assert_eq!(PrimitiveError::Empty.to_string(), "value must not be empty");
108 }
109
110 #[test]
111 fn display_too_short() {
112 assert_eq!(
113 PrimitiveError::TooShort { min: 3, actual: 1 }.to_string(),
114 "value is too short: minimum is 3, actual is 1"
115 );
116 }
117
118 #[test]
119 fn display_too_long() {
120 assert_eq!(
121 PrimitiveError::TooLong { max: 5, actual: 8 }.to_string(),
122 "value is too long: maximum is 5, actual is 8"
123 );
124 }
125
126 #[test]
127 fn display_out_of_range() {
128 assert_eq!(
129 PrimitiveError::OutOfRange {
130 min: 1,
131 max: 100,
132 actual: 200
133 }
134 .to_string(),
135 "value is out of range: expected 1..=100, actual is 200"
136 );
137 }
138
139 #[test]
140 fn display_invalid() {
141 assert_eq!(
142 PrimitiveError::Invalid {
143 message: "bad format"
144 }
145 .to_string(),
146 "invalid value: bad format"
147 );
148 }
149
150 #[test]
151 fn kind_returns_stable_error_category() {
152 assert_eq!(PrimitiveError::Empty.kind(), PrimitiveErrorKind::Empty);
153 assert_eq!(
154 PrimitiveError::TooShort { min: 3, actual: 1 }.kind(),
155 PrimitiveErrorKind::TooShort
156 );
157 assert_eq!(
158 PrimitiveError::TooLong { max: 5, actual: 8 }.kind(),
159 PrimitiveErrorKind::TooLong
160 );
161 assert_eq!(
162 PrimitiveError::OutOfRange {
163 min: 1,
164 max: 100,
165 actual: 200
166 }
167 .kind(),
168 PrimitiveErrorKind::OutOfRange
169 );
170 assert_eq!(
171 PrimitiveError::Invalid {
172 message: "bad format"
173 }
174 .kind(),
175 PrimitiveErrorKind::InvalidFormat
176 );
177 }
178}