• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::parse::Error;
2 use core::fmt::{self, Debug, Display};
3 
4 pub(crate) enum ErrorKind {
5     Empty,
6     UnexpectedEnd(Position),
7     UnexpectedChar(Position, char),
8     UnexpectedCharAfter(Position, char),
9     ExpectedCommaFound(Position, char),
10     LeadingZero(Position),
11     Overflow(Position),
12     EmptySegment(Position),
13     IllegalCharacter(Position),
14     WildcardNotTheOnlyComparator(char),
15     UnexpectedAfterWildcard,
16     ExcessiveComparators,
17 }
18 
19 #[derive(Copy, Clone, Eq, PartialEq)]
20 pub(crate) enum Position {
21     Major,
22     Minor,
23     Patch,
24     Pre,
25     Build,
26 }
27 
28 #[cfg(feature = "std")]
29 #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
30 impl std::error::Error for Error {}
31 
32 impl Display for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result33     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34         match &self.kind {
35             ErrorKind::Empty => formatter.write_str("empty string, expected a semver version"),
36             ErrorKind::UnexpectedEnd(pos) => {
37                 write!(formatter, "unexpected end of input while parsing {}", pos)
38             }
39             ErrorKind::UnexpectedChar(pos, ch) => {
40                 write!(
41                     formatter,
42                     "unexpected character {} while parsing {}",
43                     QuotedChar(*ch),
44                     pos,
45                 )
46             }
47             ErrorKind::UnexpectedCharAfter(pos, ch) => {
48                 write!(
49                     formatter,
50                     "unexpected character {} after {}",
51                     QuotedChar(*ch),
52                     pos,
53                 )
54             }
55             ErrorKind::ExpectedCommaFound(pos, ch) => {
56                 write!(
57                     formatter,
58                     "expected comma after {}, found {}",
59                     pos,
60                     QuotedChar(*ch),
61                 )
62             }
63             ErrorKind::LeadingZero(pos) => {
64                 write!(formatter, "invalid leading zero in {}", pos)
65             }
66             ErrorKind::Overflow(pos) => {
67                 write!(formatter, "value of {} exceeds u64::MAX", pos)
68             }
69             ErrorKind::EmptySegment(pos) => {
70                 write!(formatter, "empty identifier segment in {}", pos)
71             }
72             ErrorKind::IllegalCharacter(pos) => {
73                 write!(formatter, "unexpected character in {}", pos)
74             }
75             ErrorKind::WildcardNotTheOnlyComparator(ch) => {
76                 write!(
77                     formatter,
78                     "wildcard req ({}) must be the only comparator in the version req",
79                     ch,
80                 )
81             }
82             ErrorKind::UnexpectedAfterWildcard => {
83                 formatter.write_str("unexpected character after wildcard in version req")
84             }
85             ErrorKind::ExcessiveComparators => {
86                 formatter.write_str("excessive number of version comparators")
87             }
88         }
89     }
90 }
91 
92 impl Display for Position {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result93     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
94         formatter.write_str(match self {
95             Position::Major => "major version number",
96             Position::Minor => "minor version number",
97             Position::Patch => "patch version number",
98             Position::Pre => "pre-release identifier",
99             Position::Build => "build metadata",
100         })
101     }
102 }
103 
104 impl Debug for Error {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result105     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
106         formatter.write_str("Error(\"")?;
107         Display::fmt(self, formatter)?;
108         formatter.write_str("\")")?;
109         Ok(())
110     }
111 }
112 
113 struct QuotedChar(char);
114 
115 impl Display for QuotedChar {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result116     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
117         // Standard library versions prior to https://github.com/rust-lang/rust/pull/95345
118         // print character 0 as '\u{0}'. We prefer '\0' to keep error messages
119         // the same across all supported Rust versions.
120         if self.0 == '\0' {
121             formatter.write_str("'\\0'")
122         } else {
123             write!(formatter, "{:?}", self.0)
124         }
125     }
126 }
127