1
1
use std:: borrow:: Cow ;
2
+ use std:: io:: { self , Write } ;
2
3
use std:: { cmp:: Ordering , path:: PathBuf } ;
3
4
4
5
use clap:: Parser ;
80
81
}
81
82
82
83
pub async fn execute ( args : Args ) -> miette:: Result < ( ) > {
84
+ let stdout = io:: stdout ( ) ;
83
85
let project = Project :: load_or_else_discover ( args. manifest_path . as_deref ( ) ) . ok ( ) ;
84
86
85
87
let channel_config = ChannelConfig :: default ( ) ;
@@ -116,20 +118,22 @@ pub async fn execute(args: Args) -> miette::Result<()> {
116
118
117
119
let limit = args. limit ;
118
120
119
- search_package_by_wildcard ( package_name, & package_name_filter, repo_data, limit) . await ?;
121
+ search_package_by_wildcard ( package_name, & package_name_filter, repo_data, limit, stdout)
122
+ . await ?;
120
123
}
121
124
// If package name filter doesn't contain * (wildcard), it will search and display specific package info (if any package is found)
122
125
else {
123
126
let package_name = PackageName :: try_from ( package_name_filter) . into_diagnostic ( ) ?;
124
- search_exact_package ( package_name, repo_data) . await ?;
127
+ search_exact_package ( package_name, repo_data, stdout ) . await ?;
125
128
}
126
129
127
130
Ok ( ( ) )
128
131
}
129
132
130
- async fn search_exact_package (
133
+ async fn search_exact_package < W : Write > (
131
134
package_name : PackageName ,
132
135
repo_data : Vec < SparseRepoData > ,
136
+ out : W ,
133
137
) -> miette:: Result < ( ) > {
134
138
let package_name_search = package_name. clone ( ) ;
135
139
let packages = await_in_progress (
@@ -150,101 +154,126 @@ async fn search_exact_package(
150
154
151
155
let package = packages. last ( ) ;
152
156
if let Some ( package) = package {
153
- print_package_info ( package) ;
157
+ if let Err ( e) = print_package_info ( package, out) {
158
+ if e. kind ( ) != std:: io:: ErrorKind :: BrokenPipe {
159
+ return Err ( e) . into_diagnostic ( ) ;
160
+ }
161
+ }
154
162
}
155
163
156
164
Ok ( ( ) )
157
165
}
158
166
159
- fn print_package_info ( package : & RepoDataRecord ) {
160
- println ! ( ) ;
167
+ fn print_package_info < W : Write > ( package : & RepoDataRecord , mut out : W ) -> io :: Result < ( ) > {
168
+ writeln ! ( out ) ? ;
161
169
162
170
let package = package. clone ( ) ;
163
171
let package_name = package. package_record . name . as_source ( ) ;
164
172
let build = & package. package_record . build ;
165
173
let package_info = format ! ( "{} {}" , console:: style( package_name) , console:: style( build) ) ;
166
- println ! ( "{}" , package_info) ;
167
- println ! ( "{}\n " , "-" . repeat( package_info. chars( ) . count( ) ) ) ;
174
+ writeln ! ( out , "{}" , package_info) ? ;
175
+ writeln ! ( out , "{}\n " , "-" . repeat( package_info. chars( ) . count( ) ) ) ? ;
168
176
169
- println ! (
177
+ writeln ! (
178
+ out,
170
179
"{:19} {:19}" ,
171
180
console:: style( "Name" ) ,
172
181
console:: style( package_name)
173
- ) ;
182
+ ) ? ;
174
183
175
- println ! (
184
+ writeln ! (
185
+ out,
176
186
"{:19} {:19}" ,
177
187
console:: style( "Version" ) ,
178
188
console:: style( package. package_record. version)
179
- ) ;
189
+ ) ? ;
180
190
181
- println ! (
191
+ writeln ! (
192
+ out,
182
193
"{:19} {:19}" ,
183
194
console:: style( "Build" ) ,
184
195
console:: style( build)
185
- ) ;
196
+ ) ? ;
186
197
187
198
let size = match package. package_record . size {
188
199
Some ( size) => size. to_string ( ) ,
189
200
None => String :: from ( "Not found." ) ,
190
201
} ;
191
- println ! ( "{:19} {:19}" , console:: style( "Size" ) , console:: style( size) ) ;
202
+ writeln ! (
203
+ out,
204
+ "{:19} {:19}" ,
205
+ console:: style( "Size" ) ,
206
+ console:: style( size)
207
+ ) ?;
192
208
193
209
let license = match package. package_record . license {
194
210
Some ( license) => license,
195
211
None => String :: from ( "Not found." ) ,
196
212
} ;
197
- println ! (
213
+ writeln ! (
214
+ out,
198
215
"{:19} {:19}" ,
199
216
console:: style( "License" ) ,
200
217
console:: style( license)
201
- ) ;
218
+ ) ? ;
202
219
203
- println ! (
220
+ writeln ! (
221
+ out,
204
222
"{:19} {:19}" ,
205
223
console:: style( "Subdir" ) ,
206
224
console:: style( package. package_record. subdir)
207
- ) ;
225
+ ) ? ;
208
226
209
- println ! (
227
+ writeln ! (
228
+ out,
210
229
"{:19} {:19}" ,
211
230
console:: style( "File Name" ) ,
212
231
console:: style( package. file_name)
213
- ) ;
232
+ ) ? ;
214
233
215
- println ! (
234
+ writeln ! (
235
+ out,
216
236
"{:19} {:19}" ,
217
237
console:: style( "URL" ) ,
218
238
console:: style( package. url)
219
- ) ;
239
+ ) ? ;
220
240
221
241
let md5 = match package. package_record . md5 {
222
242
Some ( md5) => format ! ( "{:x}" , md5) ,
223
243
None => "Not available" . to_string ( ) ,
224
244
} ;
225
- println ! ( "{:19} {:19}" , console:: style( "MD5" ) , console:: style( md5) ) ;
245
+ writeln ! (
246
+ out,
247
+ "{:19} {:19}" ,
248
+ console:: style( "MD5" ) ,
249
+ console:: style( md5)
250
+ ) ?;
226
251
227
252
let sha256 = match package. package_record . sha256 {
228
253
Some ( sha256) => format ! ( "{:x}" , sha256) ,
229
254
None => "Not available" . to_string ( ) ,
230
255
} ;
231
- println ! (
256
+ writeln ! (
257
+ out,
232
258
"{:19} {:19}" ,
233
259
console:: style( "SHA256" ) ,
234
260
console:: style( sha256) ,
235
- ) ;
261
+ ) ? ;
236
262
237
- println ! ( "\n Dependencies:" ) ;
263
+ writeln ! ( out , "\n Dependencies:" ) ? ;
238
264
for dependency in package. package_record . depends {
239
- println ! ( " - {}" , dependency) ;
265
+ writeln ! ( out , " - {}" , dependency) ? ;
240
266
}
267
+
268
+ Ok ( ( ) )
241
269
}
242
270
243
- async fn search_package_by_wildcard (
271
+ async fn search_package_by_wildcard < W : Write > (
244
272
package_name : PackageName ,
245
273
package_name_filter : & str ,
246
274
repo_data : Vec < SparseRepoData > ,
247
275
limit : usize ,
276
+ out : W ,
248
277
) -> miette:: Result < ( ) > {
249
278
let wildcard_pattern = Regex :: new ( & format ! ( "^{}$" , & package_name_filter. replace( '*' , ".*" ) ) )
250
279
. expect ( "Expect only characters and/or * (wildcard)." ) ;
@@ -301,18 +330,23 @@ async fn search_package_by_wildcard(
301
330
let _ = packages. split_off ( limit) ;
302
331
}
303
332
304
- print_matching_packages ( packages) ;
333
+ if let Err ( e) = print_matching_packages ( packages, out) {
334
+ if e. kind ( ) != std:: io:: ErrorKind :: BrokenPipe {
335
+ return Err ( e) . into_diagnostic ( ) ;
336
+ }
337
+ }
305
338
306
339
Ok ( ( ) )
307
340
}
308
341
309
- fn print_matching_packages ( packages : Vec < RepoDataRecord > ) {
310
- println ! (
342
+ fn print_matching_packages < W : Write > ( packages : Vec < RepoDataRecord > , mut out : W ) -> io:: Result < ( ) > {
343
+ writeln ! (
344
+ out,
311
345
"{:40} {:19} {:19}" ,
312
346
console:: style( "Package" ) . bold( ) ,
313
347
console:: style( "Version" ) . bold( ) ,
314
348
console:: style( "Channel" ) . bold( ) ,
315
- ) ;
349
+ ) ? ;
316
350
317
351
for package in packages {
318
352
// TODO: change channel fetch logic to be more robust
@@ -324,11 +358,14 @@ fn print_matching_packages(packages: Vec<RepoDataRecord>) {
324
358
let package_name = package. package_record . name ;
325
359
let version = package. package_record . version . as_str ( ) ;
326
360
327
- println ! (
361
+ writeln ! (
362
+ out,
328
363
"{:40} {:19} {:19}" ,
329
364
console:: style( package_name. as_source( ) ) . cyan( ) . bright( ) ,
330
365
console:: style( version) ,
331
366
console:: style( channel_name) ,
332
- ) ;
367
+ ) ? ;
333
368
}
369
+
370
+ Ok ( ( ) )
334
371
}
0 commit comments