1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//!
//! # Layout21 Error-Helper Utilities
//!
//! ```rust
//! use layout21utils::error::{ErrorHelper, Unwrapper};
//!
//! /// Example implementer of [`ErrorHelper`].
//! /// Typical implementers will have some internal state to report upon failure.
//! struct HasFunErrors;
//! impl ErrorHelper for HasFunErrors {
//! type Error = String;
//!
//! /// Add our extra-fun state upon failure.
//! fn err(&self, msg: impl Into<String>) -> Self::Error {
//! format!("Extra Fun Error: {}", msg.into())
//! }
//! }
//! impl HasFunErrors {
//! /// Demo of using the [`Unwrapper`] trait on [`Option`]s and [`Result`]s.
//! fn fun(&self) -> Result<(), String> {
//! // Unwrap an [`Option`]
//! Some(5).unwrapper(self, "Option failed!")?;
//!
//! // Unwrap a [`Result`]
//! let r: Result<(), String> = Ok(());
//! r.unwrapper(self, "Result failed!")
//! }
//! }
//! ```
//!
///
/// # ErrorHelper
///
/// Helper trait for re-use among many conversion tree-walkers.
/// Each implementer will generally have some internal state to report upon failure,
/// which it can inject in the implementation-required `err` method.
/// The `fail` method, provided by default, simply returns the `err` value.
///
///
/// # Unwrapper
///
/// Trait for post-fix application of [`ErrorHelper`] handling,
/// during the particularly common cases of unwrapping [`Option`]s and [`Result`]s.
///
/// Sole method `unwrapper` takes an [`ErrorHelper`] and string-convertible error-message as arguments,
/// and returns a [`Result`] of the [`ErrorHelper`]'s associated error type.
///
/// Example:
///
/// ```rust
/// use layout21utils::error::{ErrorHelper, Unwrapper};
///
/// fn example(h: &impl ErrorHelper<Error=String>) -> Result<(), String> {
/// // Unwrap an [`Option`]
/// Some(5).unwrapper(h, "Option failed!")?;
///
/// // Unwrap a [`Result`]
/// let r: Result<(), String> = Ok(());
/// r.unwrapper(h, "Result failed!")
/// }
/// ```
///
/// The typical usage of [`Unwrapper`] is not to implement it for new types,
/// but to just import the trait and use it on the standard library [`Option`] and [`Result`] types.
/// And while not required, said usages are generally expected to be
/// in the context of a type that implements [`ErrorHelper`].
///