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