11
11
//! Manticore code *should not* call into the [`log`] crate directly outside of
12
12
//! this module.
13
13
14
+ // TODO: Remove this once we start using these macros in Manticore.
14
15
#![ allow( unused) ]
15
16
17
+ use core:: fmt;
18
+
16
19
#[ cfg( doc) ]
17
20
use __raw_log as log;
18
21
22
+ /// A wrapped Manticore error.
23
+ ///
24
+ /// This type should always be referred to as `manticore::Error`. It represents
25
+ /// an error with extra (potentially redacted) information attached. This type
26
+ /// cannot be directly created by users of the library.
27
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
28
+ pub struct Error < E > {
29
+ inner : E ,
30
+ }
31
+
32
+ impl < E > Error < E > {
33
+ /// Creates a new `Error`. This function is an implementation detail,
34
+ /// and should not be called by users.
35
+ #[ doc( hidden) ]
36
+ pub fn __new ( inner : E ) -> Self {
37
+ Self { inner }
38
+ }
39
+
40
+ /// Transforms the wrapper error by way of an [`Into`] conversion.
41
+ ///
42
+ /// Generally, this function should not be necessary, because Manticore-
43
+ /// defined error types manually implement the relevant [`From`]
44
+ /// implementations for `manticore::Error`, which in turn call `cast()`.
45
+ pub fn cast < F : From < E > > ( self ) -> Error < F > {
46
+ Error {
47
+ inner : self . inner . into ( ) ,
48
+ }
49
+ }
50
+
51
+ /// Gets the wrapped error.
52
+ pub fn into_inner ( self ) -> E {
53
+ self . inner
54
+ }
55
+ }
56
+
57
+ impl < E > AsRef < E > for Error < E > {
58
+ fn as_ref ( & self ) -> & E {
59
+ & self . inner
60
+ }
61
+ }
62
+
63
+ impl < E > AsMut < E > for Error < E > {
64
+ fn as_mut ( & mut self ) -> & mut E {
65
+ & mut self . inner
66
+ }
67
+ }
68
+
69
+ impl < E : fmt:: Display > fmt:: Display for Error < E > {
70
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
71
+ struct DisplayAsDebug < ' a , E > ( & ' a E ) ;
72
+ impl < E : fmt:: Display > fmt:: Debug for DisplayAsDebug < ' _ , E > {
73
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
74
+ self . 0 . fmt ( f)
75
+ }
76
+ }
77
+
78
+ f. debug_struct ( "manticore::Error" )
79
+ . field ( "inner" , & DisplayAsDebug ( & self . inner ) )
80
+ . finish ( )
81
+ }
82
+ }
83
+
84
+ /// Generates `From` implementations for `manticore::Error`.
85
+ ///
86
+ /// We would like to write this `impl`:
87
+ /// ```compile_fail
88
+ /// # use manticore::Error;
89
+ /// impl<E1, E2> From<Error<E1>> for Error<E2> where E2: From<E1> {
90
+ /// fn from(e: Error<E1>) -> Error<E2> {
91
+ /// e.cast()
92
+ /// }
93
+ /// }
94
+ /// ```
95
+ ///
96
+ /// Unfortunately, the trait coherence rules mean that for `E1 == E2`,
97
+ /// this conflicts with the standard library's `impl<T> From<T> for T`
98
+ /// impl. We work around this by calling this macro for every Manticore
99
+ /// error definition that has `From` impls.
100
+ macro_rules! debug_from {
101
+ ( $e: ident<$trait: ident: $bound: path> => $( $f: ty) ,+ $( , ) ?) => { $(
102
+ impl <$trait: $bound> From <$crate:: Error <$f>> for $crate:: Error <$e<$trait>> {
103
+ fn from( e: $crate:: Error <$f>) -> Self {
104
+ e. cast( )
105
+ }
106
+ }
107
+ ) * } ;
108
+ ( $e: ty => $( $f: ty) ,+ $( , ) ?) => { $(
109
+ impl From <$crate:: Error <$f>> for $crate:: Error <$e> {
110
+ fn from( e: $crate:: Error <$f>) -> Self {
111
+ e. cast( )
112
+ }
113
+ }
114
+ ) * } ;
115
+ }
116
+
19
117
/// Checks a condition, logging if it fails.
20
118
///
21
119
/// If the condition does not hold, constructs the given error, logs it, and
22
120
/// returns out of the current function with it.
23
121
macro_rules! check {
24
122
( $cond: expr, $error: expr) => {
25
123
if !$cond {
26
- let e = $error;
27
- error!(
28
- "check failure: `{}`; returned {:?}"
29
- stringify!( $cond) , e
30
- ) ;
31
- return Err ( e) ;
124
+ let error = $error;
125
+ fail!(
126
+ error,
127
+ "check failure: `{}`; returned {:?}" ,
128
+ stringify!( $cond) ,
129
+ error,
130
+ ) ?;
32
131
}
33
- }
132
+ } ;
34
133
}
35
134
36
135
/// Logs a newly-created error value and returns it.
37
136
///
38
- /// This function is useful for marking where errors originate in tests.
137
+ /// This macro is the main way to generate [`Error`] values.
138
+ ///
39
139
/// For example, instead of writing `foo.ok_or(MyError)`, instead write
40
- /// `foo.ok_or_else(|| trace !(MyError))`.
41
- macro_rules! trace {
140
+ /// `foo.ok_or_else(|| fail !(MyError))`.
141
+ macro_rules! fail {
42
142
( $error: expr, $( $format: tt) +) => { {
43
143
error!( $( $format) +) ;
44
- $ error
144
+ Err ( $crate :: debug :: Error :: __new ( $ error) )
45
145
} } ;
46
146
( $error: expr) => { {
47
- let e = $error;
48
- error!( "generated error: `{:?}`" , e ) ;
49
- e
147
+ let error = $error;
148
+ error!( "generated error: `{:?}`" , error ) ;
149
+ Err ( $crate :: debug :: Error :: __new ( error ) )
50
150
} } ;
51
151
}
52
152
153
+ /// Redactable version of [`log::trace!()`].
154
+ macro_rules! trace {
155
+ ( $( $args: tt) * ) => {
156
+ #[ cfg( feature = "log" ) ]
157
+ let _ = __raw_log:: trace!( $( $args) * ) ;
158
+ }
159
+ }
160
+
53
161
/// Redactable version of [`log::info!()`].
54
162
macro_rules! info {
55
163
( $( $args: tt) * ) => {
@@ -78,7 +186,7 @@ macro_rules! error {
78
186
/// test binary.
79
187
///
80
188
/// This needs to happen here, since the test binary's main() cannot be
81
- /// overriden .
189
+ /// overridden .
82
190
#[ cfg( test) ]
83
191
#[ ctor:: ctor]
84
192
fn init_test_logger ( ) {
@@ -90,7 +198,7 @@ fn init_test_logger() {
90
198
let name = thread. name ( ) . unwrap_or ( "<unknown>" ) ;
91
199
for line in record. args ( ) . to_string ( ) . trim ( ) . lines ( ) {
92
200
// NOTE: we explicitly print to stderr, since this allows the
93
- // Rust test harness to supress log statements originating from
201
+ // Rust test harness to suppress log statements originating from
94
202
// passing tests.
95
203
eprintln ! (
96
204
"[{level}({thread}) {file}:{line}] {msg}" ,
0 commit comments