12
12
//! .unwrap();
13
13
//! ```
14
14
15
+ use std:: error:: Error ;
15
16
use std:: ffi;
17
+ use std:: fmt;
16
18
use std:: path;
17
19
use std:: process;
18
20
19
21
use escargot;
20
- use failure;
21
22
22
23
/// Create a `Command` for a `bin` in the Cargo project.
23
24
pub trait CommandCargoExt
39
40
/// .unwrap()
40
41
/// .unwrap();
41
42
/// ```
42
- fn main_binary ( ) -> Result < Self , failure :: Error > ;
43
+ fn main_binary ( ) -> Result < Self , CargoError > ;
43
44
44
45
/// Create a `Command` to run a specific binary of the current crate.
45
46
///
54
55
/// .unwrap()
55
56
/// .unwrap();
56
57
/// ```
57
- fn cargo_bin < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , failure :: Error > ;
58
+ fn cargo_bin < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , CargoError > ;
58
59
59
60
/// Create a `Command` to run a specific example of the current crate.
60
61
///
@@ -69,21 +70,21 @@ where
69
70
/// .unwrap()
70
71
/// .unwrap();
71
72
/// ```
72
- fn cargo_example < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , failure :: Error > ;
73
+ fn cargo_example < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , CargoError > ;
73
74
}
74
75
75
76
impl CommandCargoExt for process:: Command {
76
- fn main_binary ( ) -> Result < Self , failure :: Error > {
77
+ fn main_binary ( ) -> Result < Self , CargoError > {
77
78
let cmd = main_binary_path ( ) ?;
78
79
Ok ( process:: Command :: new ( & cmd) )
79
80
}
80
81
81
- fn cargo_bin < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , failure :: Error > {
82
+ fn cargo_bin < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , CargoError > {
82
83
let cmd = cargo_bin_path ( name) ?;
83
84
Ok ( process:: Command :: new ( & cmd) )
84
85
}
85
86
86
- fn cargo_example < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , failure :: Error > {
87
+ fn cargo_example < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < Self , CargoError > {
87
88
let cmd = cargo_example_path ( name) ?;
88
89
Ok ( process:: Command :: new ( & cmd) )
89
90
}
@@ -126,41 +127,103 @@ fn extract_filenames(msg: &escargot::Message, kind: &str) -> Option<path::PathBu
126
127
/// Get the path to the crate's main binary.
127
128
///
128
129
/// Note: only works if there one bin in the crate.
129
- pub fn main_binary_path ( ) -> Result < path:: PathBuf , failure :: Error > {
130
+ pub fn main_binary_path ( ) -> Result < path:: PathBuf , CargoError > {
130
131
let cargo = escargot:: Cargo :: new ( ) . build ( ) . current_release ( ) ;
131
132
let bins: Vec < _ > = cargo
132
- . exec ( ) ?
133
+ . exec ( )
134
+ . map_err ( |e| CargoError :: with_cause ( e) ) ?
133
135
. filter_map ( |m| extract_filenames ( & m, "bin" ) )
134
136
. collect ( ) ;
135
137
if bins. is_empty ( ) {
136
- bail ! ( "No binaries in crate" ) ;
138
+ return Err ( CargoError :: with_context ( "No binaries in crate" ) ) ;
137
139
} else if bins. len ( ) != 1 {
138
- bail ! ( "Ambiguous which binary is intended: {:?}" , bins) ;
140
+ return Err ( CargoError :: with_context ( format ! (
141
+ "Ambiguous which binary is intended: {:?}" ,
142
+ bins
143
+ ) ) ) ;
139
144
}
140
145
Ok ( bins. into_iter ( ) . next ( ) . expect ( "already validated" ) )
141
146
}
142
147
143
148
/// Get the path to the specified binary of the current crate.
144
- pub fn cargo_bin_path < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < path:: PathBuf , failure :: Error > {
149
+ pub fn cargo_bin_path < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < path:: PathBuf , CargoError > {
145
150
let cargo = escargot:: Cargo :: new ( ) . build ( ) . bin ( name) . current_release ( ) ;
146
151
let bins: Vec < _ > = cargo
147
- . exec ( ) ?
152
+ . exec ( )
153
+ . map_err ( |e| CargoError :: with_cause ( e) ) ?
148
154
. filter_map ( |m| extract_filenames ( & m, "bin" ) )
149
155
. collect ( ) ;
150
156
assert_eq ! ( bins. len( ) , 1 ) ;
151
157
Ok ( bins. into_iter ( ) . next ( ) . expect ( "already validated" ) )
152
158
}
153
159
154
160
/// Get the path to the specified example of the current crate.
155
- pub fn cargo_example_path < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < path:: PathBuf , failure :: Error > {
161
+ pub fn cargo_example_path < S : AsRef < ffi:: OsStr > > ( name : S ) -> Result < path:: PathBuf , CargoError > {
156
162
let cargo = escargot:: Cargo :: new ( )
157
163
. build ( )
158
164
. example ( name)
159
165
. current_release ( ) ;
160
166
let bins: Vec < _ > = cargo
161
- . exec ( ) ?
167
+ . exec ( )
168
+ . map_err ( |e| CargoError :: with_cause ( e) ) ?
162
169
. filter_map ( |m| extract_filenames ( & m, "example" ) )
163
170
. collect ( ) ;
164
171
assert_eq ! ( bins. len( ) , 1 ) ;
165
172
Ok ( bins. into_iter ( ) . next ( ) . expect ( "already validated" ) )
166
173
}
174
+
175
+ /// Error when finding crate binary.
176
+ #[ derive( Debug ) ]
177
+ pub struct CargoError {
178
+ context : Option < String > ,
179
+ cause : Option < Box < Error + Send + Sync + ' static > > ,
180
+ }
181
+
182
+ impl CargoError {
183
+ fn with_context < S > ( context : S ) -> Self
184
+ where
185
+ S : Into < String > ,
186
+ {
187
+ let context = context. into ( ) ;
188
+ Self {
189
+ context : Some ( context) ,
190
+ cause : None ,
191
+ }
192
+ }
193
+
194
+ fn with_cause < E > ( cause : E ) -> Self
195
+ where
196
+ E : Error + Send + Sync + ' static ,
197
+ {
198
+ let cause = Box :: new ( cause) ;
199
+ Self {
200
+ context : None ,
201
+ cause : Some ( cause) ,
202
+ }
203
+ }
204
+ }
205
+
206
+ impl Error for CargoError {
207
+ fn description ( & self ) -> & str {
208
+ "Cargo command failed."
209
+ }
210
+
211
+ fn cause ( & self ) -> Option < & Error > {
212
+ self . cause . as_ref ( ) . map ( |c| {
213
+ let c: & Error = c. as_ref ( ) ;
214
+ c
215
+ } )
216
+ }
217
+ }
218
+
219
+ impl fmt:: Display for CargoError {
220
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
221
+ if let Some ( ref context) = self . context {
222
+ writeln ! ( f, "{}" , context) ?;
223
+ }
224
+ if let Some ( ref cause) = self . cause {
225
+ writeln ! ( f, "Cause: {}" , cause) ?;
226
+ }
227
+ Ok ( ( ) )
228
+ }
229
+ }
0 commit comments