@@ -26,6 +26,9 @@ pub struct ListImages {
26
26
/// Container engine (such as docker or podman).
27
27
#[ clap( long) ]
28
28
pub engine : Option < String > ,
29
+ /// Output format
30
+ #[ clap( long, default_value = "human" ) ]
31
+ pub format : OutputFormat ,
29
32
/// Only list images for specific target(s). By default, list all targets.
30
33
pub targets : Vec < String > ,
31
34
}
@@ -36,6 +39,25 @@ impl ListImages {
36
39
}
37
40
}
38
41
42
+ #[ derive( Clone , Debug ) ]
43
+ pub enum OutputFormat {
44
+ Human ,
45
+ Json ,
46
+ }
47
+
48
+ impl clap:: ValueEnum for OutputFormat {
49
+ fn value_variants < ' a > ( ) -> & ' a [ Self ] {
50
+ & [ Self :: Human , Self :: Json ]
51
+ }
52
+
53
+ fn to_possible_value < ' a > ( & self ) -> Option < clap:: PossibleValue < ' a > > {
54
+ match self {
55
+ OutputFormat :: Human => Some ( clap:: PossibleValue :: new ( "human" ) ) ,
56
+ OutputFormat :: Json => Some ( clap:: PossibleValue :: new ( "json" ) ) ,
57
+ }
58
+ }
59
+ }
60
+
39
61
#[ derive( Args , Debug ) ]
40
62
pub struct RemoveImages {
41
63
/// If not provided, remove all images.
@@ -118,7 +140,7 @@ impl Images {
118
140
}
119
141
}
120
142
121
- #[ derive( Debug , PartialOrd , Ord , PartialEq , Eq ) ]
143
+ #[ derive( Debug , PartialOrd , Ord , PartialEq , Eq , serde :: Serialize ) ]
122
144
struct Image {
123
145
repository : String ,
124
146
tag : String ,
@@ -258,7 +280,9 @@ fn get_image_target(
258
280
}
259
281
260
282
pub fn list_images (
261
- ListImages { targets, .. } : ListImages ,
283
+ ListImages {
284
+ targets, format, ..
285
+ } : ListImages ,
262
286
engine : & docker:: Engine ,
263
287
msg_info : & mut MessageInfo ,
264
288
) -> cross:: Result < ( ) > {
@@ -281,45 +305,55 @@ pub fn list_images(
281
305
let mut keys: Vec < & str > = map. keys ( ) . map ( |k| k. as_ref ( ) ) . collect ( ) ;
282
306
keys. sort_unstable ( ) ;
283
307
284
- let print_string =
285
- |col1 : & str , col2 : & str , fill : char , info : & mut MessageInfo | -> cross:: Result < ( ) > {
286
- let mut row = String :: new ( ) ;
287
- row. push ( '|' ) ;
288
- row. push ( fill) ;
289
- row. push_str ( col1) ;
290
- let spaces = max_target_len. max ( col1. len ( ) ) + 1 - col1. len ( ) ;
291
- for _ in 0 ..spaces {
292
- row. push ( fill) ;
293
- }
294
- row. push ( '|' ) ;
295
- row. push ( fill) ;
296
- row. push_str ( col2) ;
297
- let spaces = max_image_len. max ( col2. len ( ) ) + 1 - col2. len ( ) ;
298
- for _ in 0 ..spaces {
299
- row. push ( fill) ;
308
+ match format {
309
+ OutputFormat :: Json => {
310
+ msg_info. info ( format_args ! ( "{}" , serde_json:: to_string( & map) ?) ) ?;
311
+ }
312
+ OutputFormat :: Human => {
313
+ let print_string =
314
+ |col1 : & str , col2 : & str , fill : char , info : & mut MessageInfo | -> cross:: Result < ( ) > {
315
+ let mut row = String :: new ( ) ;
316
+ row. push ( '|' ) ;
317
+ row. push ( fill) ;
318
+ row. push_str ( col1) ;
319
+ let spaces = max_target_len. max ( col1. len ( ) ) + 1 - col1. len ( ) ;
320
+ for _ in 0 ..spaces {
321
+ row. push ( fill) ;
322
+ }
323
+ row. push ( '|' ) ;
324
+ row. push ( fill) ;
325
+ row. push_str ( col2) ;
326
+ let spaces = max_image_len. max ( col2. len ( ) ) + 1 - col2. len ( ) ;
327
+ for _ in 0 ..spaces {
328
+ row. push ( fill) ;
329
+ }
330
+ row. push ( '|' ) ;
331
+ info. print ( row)
332
+ } ;
333
+
334
+ if targets. len ( ) != 1 {
335
+ print_string ( "Targets" , "Images" , ' ' , msg_info) ?;
336
+ print_string ( "-------" , "------" , '-' , msg_info) ?;
300
337
}
301
- row. push ( '|' ) ;
302
- info. print ( row)
303
- } ;
304
-
305
- if targets. len ( ) != 1 {
306
- print_string ( "Targets" , "Images" , ' ' , msg_info) ?;
307
- print_string ( "-------" , "------" , '-' , msg_info) ?;
308
- }
309
338
310
- let print_single =
311
- |_: & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > { info. print ( image) } ;
312
- let print_table = |target : & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > {
313
- let name = image. name ( ) ;
314
- print_string ( target, & name, ' ' , info)
315
- } ;
316
-
317
- for target in keys {
318
- for image in map. get ( target) . expect ( "map must have key" ) . iter ( ) {
319
- if targets. len ( ) == 1 {
320
- print_single ( target, image, msg_info) ?;
321
- } else {
322
- print_table ( target, image, msg_info) ?;
339
+ let print_single = |_: & str ,
340
+ image : & Image ,
341
+ info : & mut MessageInfo |
342
+ -> cross:: Result < ( ) > { info. print ( image) } ;
343
+ let print_table =
344
+ |target : & str , image : & Image , info : & mut MessageInfo | -> cross:: Result < ( ) > {
345
+ let name = image. name ( ) ;
346
+ print_string ( target, & name, ' ' , info)
347
+ } ;
348
+
349
+ for target in keys {
350
+ for image in map. get ( target) . expect ( "map must have key" ) . iter ( ) {
351
+ if targets. len ( ) == 1 {
352
+ print_single ( target, image, msg_info) ?;
353
+ } else {
354
+ print_table ( target, image, msg_info) ?;
355
+ }
356
+ }
323
357
}
324
358
}
325
359
}
0 commit comments