1use core::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub(crate) enum SemverErrorKind {
6 UnexpectedCharacter(char),
8 MaxLengthExceeded,
10 MaxSafeIntegerExceeded,
12 Empty,
14 EmptySegment,
16 TrailingDot,
18 UnexpectedDot,
20 LeadingZero,
22 InvalidNumber,
24 MissingVersionSegment,
26 MissingVersionAfterOperator(&'static str),
28}
29
30impl fmt::Display for SemverErrorKind {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 match self {
33 Self::UnexpectedCharacter(ch) => write!(f, "unexpected character: '{ch}'"),
34 Self::MaxLengthExceeded => f.write_str("maximum length of 256 characters exceeded"),
35 Self::MaxSafeIntegerExceeded => f.write_str("number exceeds MAX_SAFE_INTEGER"),
36 Self::Empty => f.write_str("empty"),
37 Self::EmptySegment => f.write_str("empty segment"),
38 Self::TrailingDot => f.write_str("trailing dot"),
39 Self::UnexpectedDot => f.write_str("unexpected dot"),
40 Self::LeadingZero => f.write_str("leading zero"),
41 Self::InvalidNumber => f.write_str("invalid number"),
42 Self::MissingVersionSegment => f.write_str("missing version segment"),
43 Self::MissingVersionAfterOperator(operator) => {
44 write!(f, "missing version after {operator}")
45 }
46 }
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
66pub struct SemverError {
67 kind: SemverErrorKind,
68}
69
70impl fmt::Display for SemverError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 self.kind.fmt(f)
73 }
74}
75
76#[cfg(feature = "std")]
77impl std::error::Error for SemverError {}
78
79impl From<SemverErrorKind> for SemverError {
80 fn from(kind: SemverErrorKind) -> Self {
81 Self { kind }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 #[cfg(not(feature = "std"))]
88 use alloc::string::ToString;
89
90 use super::{SemverError, SemverErrorKind};
91
92 #[test]
93 fn semver_error_kind_display_variants() {
94 let cases = [
95 (
96 SemverErrorKind::UnexpectedCharacter('x'),
97 "unexpected character: 'x'",
98 ),
99 (
100 SemverErrorKind::MaxLengthExceeded,
101 "maximum length of 256 characters exceeded",
102 ),
103 (
104 SemverErrorKind::MaxSafeIntegerExceeded,
105 "number exceeds MAX_SAFE_INTEGER",
106 ),
107 (SemverErrorKind::Empty, "empty"),
108 (SemverErrorKind::EmptySegment, "empty segment"),
109 (SemverErrorKind::TrailingDot, "trailing dot"),
110 (SemverErrorKind::UnexpectedDot, "unexpected dot"),
111 (SemverErrorKind::LeadingZero, "leading zero"),
112 (SemverErrorKind::InvalidNumber, "invalid number"),
113 (
114 SemverErrorKind::MissingVersionSegment,
115 "missing version segment",
116 ),
117 (
118 SemverErrorKind::MissingVersionAfterOperator(">="),
119 "missing version after >=",
120 ),
121 ];
122
123 for (kind, expected) in cases {
124 assert_eq!(kind.to_string(), expected);
125 let error: SemverError = kind.into();
126 assert_eq!(error.to_string(), expected);
127 }
128 }
129}