1use std::{self, error, fmt, io, str};
2use semver::{self, Identifier};
3
4/// The error type for this crate.
5#[derive(Debug)]
6pub enum Error {
7 /// An error ocurrend when executing the `rustc` command.
8 CouldNotExecuteCommand(io::Error),
9 /// The output of `rustc -vV` was not valid utf-8.
10 Utf8Error(str::Utf8Error),
11 /// The output of `rustc -vV` was not in the expected format.
12 UnexpectedVersionFormat,
13 /// An error ocurred in parsing a `VersionReq`.
14 ReqParseError(semver::ReqParseError),
15 /// An error ocurred in parsing the semver.
16 SemVerError(semver::SemVerError),
17 /// The pre-release tag is unknown.
18 UnknownPreReleaseTag(Identifier),
19}
20use Error::*;
21
22impl fmt::Display for Error {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 use std::error::Error;
25 match *self {
26 CouldNotExecuteCommand(ref e: &Error) => write!(f, "{}: {}", self.description(), e),
27 Utf8Error(_) => write!(f, "{}", self.description()),
28 UnexpectedVersionFormat => write!(f, "{}", self.description()),
29 ReqParseError(ref e: &ReqParseError) => write!(f, "{}: {}", self.description(), e),
30 SemVerError(ref e: &SemVerError) => write!(f, "{}: {}", self.description(), e),
31 UnknownPreReleaseTag(ref i: &Identifier) => write!(f, "{}: {}", self.description(), i),
32 }
33 }
34}
35
36impl error::Error for Error {
37 fn cause(&self) -> Option<&dynerror::Error> {
38 match *self {
39 CouldNotExecuteCommand(ref e: &Error) => Some(e),
40 Utf8Error(ref e: &Utf8Error) => Some(e),
41 UnexpectedVersionFormat => None,
42 ReqParseError(ref e: &ReqParseError) => Some(e),
43 SemVerError(ref e: &SemVerError) => Some(e),
44 UnknownPreReleaseTag(_) => None,
45 }
46 }
47
48 fn description(&self) -> &str {
49 match *self {
50 CouldNotExecuteCommand(_) => "could not execute command",
51 Utf8Error(_) => "invalid UTF-8 output from `rustc -vV`",
52 UnexpectedVersionFormat => "unexpected `rustc -vV` format",
53 ReqParseError(_) => "error parsing version requirement",
54 SemVerError(_) => "error parsing version",
55 UnknownPreReleaseTag(_) => "unknown pre-release tag",
56 }
57 }
58}
59
60macro_rules! impl_from {
61 ($($err_ty:ty => $variant:ident),* $(,)*) => {
62 $(
63 impl From<$err_ty> for Error {
64 fn from(e: $err_ty) -> Error {
65 Error::$variant(e)
66 }
67 }
68 )*
69 }
70}
71
72impl_from! {
73 str::Utf8Error => Utf8Error,
74 semver::SemVerError => SemVerError,
75 semver::ReqParseError => ReqParseError,
76}
77
78/// The result type for this crate.
79pub type Result<T> = std::result::Result<T, Error>;
80