giveup/
hint.rs

1/// Add an example message to an object.
2pub trait Example<'a> {
3	/// Consumes and returns `self` combined with the
4	/// given `example` message.
5	fn example(self, example: &'a str) -> Self;
6}
7
8/// Implementation of `Example` on any `Result`s returned by
9/// [`hint`](crate::Giveup::hint)
10impl<'a, T, E> Example<'a> for Result<T, HintedError<'a, E>>
11where
12	E: std::fmt::Display + Send + Sync,
13{
14	fn example(mut self, example: &'a str) -> Self {
15		if let Err(ref mut e) = self {
16			e.hint.example = Some(example);
17		}
18		self
19	}
20}
21
22
23pub struct HintedError<'a, E> {
24	e: E,
25	hint: Hint<'a>,
26}
27
28impl<'a, E> HintedError<'a, E>
29where
30	E: std::fmt::Display + Send + Sync,
31{
32	pub fn from_hint(e: E, hint: &'a str) -> Self {
33		Self {
34			e,
35			hint: Hint{ hint, example: None },
36		}
37	}
38}
39
40impl<'a, E> std::fmt::Display for HintedError<'a, E>
41where
42	E: std::fmt::Display + Send + Sync,
43{
44	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
45		write!(f, "{}\n{}", self.e, self.hint)
46	}
47}
48
49struct Hint<'a> {
50	hint: &'a str,
51	example: Option<&'a str>,
52}
53
54impl<'a> std::fmt::Display for Hint<'a> {
55	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
56		match self.example {
57			Some(example) => write!(f, "{}: `{}`", self.hint, example),
58			None => write!(f, "{}", self.hint),
59		}
60	}
61}