must/
errors.rs

1use std;
2use std::fmt::{self, Debug, Display, Formatter};
3
4#[derive(Debug)]
5pub struct Error {
6	/// Dumped using debug trait.
7	pub got: String,
8	pub kind: ErrorKind,
9}
10
11
12/// Common prefix: (so do not incude it in separate message)
13///
14/// {} must
15///
16///
17///
18#[derive(Debug)]
19pub enum ErrorKind {
20	MustEq { to: String },
21	MustNotEq { to: String },
22	MustBeOk,
23	MustBeErr,
24	MustBeSome,
25	MustBeNone,
26	MustHaveLength { len: usize },
27	MustBeEmpty,
28	MustBeInRange { range: String },
29	MustNotBeInRange { range: String },
30	MustBeLowercase,
31	MustBeUppercase,
32	MustBeAscii,
33	MustBeEqAsciiIgnoreCase { to: String },
34	MustBeLessThan { other: String },
35	MustBeLessThanOrEqual { other: String },
36	MustBeGreaterThan { other: String },
37	MustBeGreaterThanOrEqual { other: String },
38	MustBeNan,
39	MustNotBeNan,
40
41	Msg(String),
42	Error(Box<std::error::Error>),
43}
44
45impl Display for ErrorKind {
46	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
47		use self::ErrorKind::*;
48		match self {
49			&MustEq { ref to } => write!(f, "must be {}", to),
50			&MustNotEq { ref to } => write!(f, "must not be {}", to),
51			&MustBeOk => write!(f, "must be ok"),
52			&MustBeErr => write!(f, "must be err"),
53			&MustBeSome => write!(f, "must be some"),
54			&MustBeNone => write!(f, "must be none"),
55			&MustHaveLength { len } => write!(f, "must have length {}", len),
56			&MustBeEmpty => write!(f, "must be empty"),
57			&MustBeInRange { ref range } => write!(f, "must be in range {}", range),
58			&MustNotBeInRange { ref range } => write!(f, "must not be in range {}", range),
59			&MustBeLowercase => write!(f, "must be lowercase"),
60			&MustBeUppercase => write!(f, "must be uppercase"),
61			&MustBeAscii => write!(f, "must be ascii"),
62			&MustBeEqAsciiIgnoreCase { ref to } => write!(f, "must eq ignore ascii case {}", to),
63			&MustBeLessThan { ref other } => write!(f, "must be less than {}", other),
64			&MustBeLessThanOrEqual { ref other } => {
65				write!(f, "must be less than or equal {}", other)
66			}
67			&MustBeGreaterThan { ref other } => write!(f, "must be greater than {}", other),
68			&MustBeGreaterThanOrEqual { ref other } => {
69				write!(f, "must be greater than or equal to {}", other)
70			}
71			&MustBeNan => write!(f, "must be NAN"),
72			&MustNotBeNan => write!(f, "must not be NAN"),
73
74			&Msg(ref msg) => write!(f, "{}", msg),
75
76			// TODO(kdy): cause chain
77			&Error(ref err) => write!(f, "{}", err.description()),
78		}
79	}
80}
81
82/// shortcut for
83/// format!("{:?}", t)
84pub fn dump<T: Debug>(t: T) -> String {
85	format!("{:?}", t)
86}
87
88
89
90/// Used from [ErrorKind.but_got][].
91///
92/// [ErrorKind.but_got]:enum.ErrorKind.html#method.but_got
93pub trait FromError {
94	fn from_err(err: ErrorKind, got: String) -> Self;
95}
96
97impl ErrorKind {
98	pub fn but_got<T: Debug, R: FromError>(self, got: T) -> R {
99		R::from_err(self, dump(got))
100	}
101}
102
103impl<O: Debug> FromError for Result<O, Error> {
104	fn from_err(err: ErrorKind, got: String) -> Self {
105		Err(Error {
106			got: got,
107			kind: err,
108		})
109	}
110}