6
6
//! - `CheckOutput`: implemented on anything that is an output type for validation against an
7
7
//! expected value.
8
8
9
- use std:: fmt;
9
+ use std:: panic:: { RefUnwindSafe , UnwindSafe } ;
10
+ use std:: { fmt, panic} ;
10
11
11
12
use anyhow:: { Context , anyhow, bail, ensure} ;
12
13
use libm:: support:: Hexf ;
@@ -20,9 +21,25 @@ use crate::{
20
21
///
21
22
/// Implemented on the tuple with the function signature as the generic (so we can use the same
22
23
/// tuple for multiple signatures).
23
- pub trait TupleCall < Func > : fmt:: Debug {
24
+ pub trait TupleCall < Func > : Copy + fmt:: Debug + Sized {
24
25
type Output ;
25
26
fn call ( self , f : Func ) -> Self :: Output ;
27
+
28
+ /// Intercept panics and print the input to stderr before continuing.
29
+ fn call_intercept_panics ( self , f : Func ) -> Self :: Output
30
+ where
31
+ Self : RefUnwindSafe ,
32
+ Func : UnwindSafe ,
33
+ {
34
+ let res = panic:: catch_unwind ( || self . call ( f) ) ;
35
+ match res {
36
+ Ok ( v) => v,
37
+ Err ( e) => {
38
+ eprintln ! ( "panic with the following input: {self:?}" ) ;
39
+ panic:: resume_unwind ( e)
40
+ }
41
+ }
42
+ }
26
43
}
27
44
28
45
/// A trait to implement on any output type so we can verify it in a generic way.
@@ -48,7 +65,7 @@ pub trait Hex: Copy {
48
65
49
66
impl < T1 , R > TupleCall < fn ( T1 ) -> R > for ( T1 , )
50
67
where
51
- T1 : fmt:: Debug ,
68
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
52
69
{
53
70
type Output = R ;
54
71
59
76
60
77
impl < T1 , T2 , R > TupleCall < fn ( T1 , T2 ) -> R > for ( T1 , T2 )
61
78
where
62
- T1 : fmt:: Debug ,
63
- T2 : fmt:: Debug ,
79
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
80
+ T2 : RefUnwindSafe + fmt:: Debug + Copy ,
64
81
{
65
82
type Output = R ;
66
83
71
88
72
89
impl < T1 , T2 , R > TupleCall < fn ( T1 , & mut T2 ) -> R > for ( T1 , )
73
90
where
74
- T1 : fmt:: Debug ,
75
- T2 : fmt:: Debug + Default ,
91
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
92
+ T2 : RefUnwindSafe + fmt:: Debug + Copy + Default ,
76
93
{
77
94
type Output = ( R , T2 ) ;
78
95
84
101
85
102
impl < T1 , T2 , T3 , R > TupleCall < fn ( T1 , T2 , T3 ) -> R > for ( T1 , T2 , T3 )
86
103
where
87
- T1 : fmt:: Debug ,
88
- T2 : fmt:: Debug ,
89
- T3 : fmt:: Debug ,
104
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
105
+ T2 : RefUnwindSafe + fmt:: Debug + Copy ,
106
+ T3 : RefUnwindSafe + fmt:: Debug + Copy ,
90
107
{
91
108
type Output = R ;
92
109
97
114
98
115
impl < T1 , T2 , T3 , R > TupleCall < fn ( T1 , T2 , & mut T3 ) -> R > for ( T1 , T2 )
99
116
where
100
- T1 : fmt:: Debug ,
101
- T2 : fmt:: Debug ,
102
- T3 : fmt:: Debug + Default ,
117
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
118
+ T2 : RefUnwindSafe + fmt:: Debug + Copy ,
119
+ T3 : RefUnwindSafe + fmt:: Debug + Copy + Default ,
103
120
{
104
121
type Output = ( R , T3 ) ;
105
122
@@ -111,9 +128,9 @@ where
111
128
112
129
impl < T1 , T2 , T3 > TupleCall < for <' a > fn ( T1 , & ' a mut T2 , & ' a mut T3 ) > for ( T1 , )
113
130
where
114
- T1 : fmt:: Debug ,
115
- T2 : fmt:: Debug + Default ,
116
- T3 : fmt:: Debug + Default ,
131
+ T1 : RefUnwindSafe + fmt:: Debug + Copy ,
132
+ T2 : RefUnwindSafe + fmt:: Debug + Copy + Default ,
133
+ T3 : RefUnwindSafe + fmt:: Debug + Copy + Default ,
117
134
{
118
135
type Output = ( T2 , T3 ) ;
119
136
0 commit comments