1
1
use clap:: Args ;
2
+ use color_eyre:: eyre:: { eyre, Result } ;
3
+ use serde:: Serialize ;
2
4
3
- use crate :: otp:: otp_element:: OTPDatabase ;
5
+ use crate :: otp:: otp_element:: { OTPDatabase , OTPElement } ;
4
6
5
7
use super :: SubcommandExecutor ;
6
8
@@ -33,13 +35,41 @@ impl Default for ListFormat {
33
35
}
34
36
}
35
37
38
+ /// Defines JSON structure to output using the --json argument in the list subcommand
39
+ #[ derive( Serialize ) ]
40
+ struct JsonOtpList < ' a > {
41
+ issuer : & ' a str ,
42
+ label : & ' a str ,
43
+ otp_code : String ,
44
+ }
45
+
46
+ impl < ' a > TryFrom < & ' a OTPElement > for JsonOtpList < ' a > {
47
+ type Error = color_eyre:: eyre:: Error ;
48
+
49
+ fn try_from ( value : & ' a OTPElement ) -> Result < Self , Self :: Error > {
50
+ let otp_code = value. get_otp_code ( ) ?;
51
+ Ok ( JsonOtpList {
52
+ issuer : & value. issuer ,
53
+ label : & value. label ,
54
+ otp_code,
55
+ } )
56
+ }
57
+ }
58
+
36
59
impl SubcommandExecutor for ListArgs {
37
60
fn run_command ( self , otp_database : OTPDatabase ) -> color_eyre:: Result < OTPDatabase > {
38
- otp_database
39
- . elements
40
- . iter ( )
41
- . enumerate ( )
42
- . for_each ( |( index, e) | {
61
+ let elements_iterator = otp_database. elements . iter ( ) . enumerate ( ) ;
62
+
63
+ if self . format . unwrap_or_default ( ) . json {
64
+ let json_elements = elements_iterator
65
+ . map ( |( _, element) | element. try_into ( ) )
66
+ . collect :: < Result < Vec < JsonOtpList > > > ( ) ?;
67
+
68
+ let stringified = serde_json:: to_string_pretty ( & json_elements)
69
+ . map_err ( |e| eyre ! ( "Error during JSON serialization: {:?}" , e) ) ?;
70
+ print ! ( "{stringified}" ) ;
71
+ } else {
72
+ elements_iterator. for_each ( |( index, e) | {
43
73
println ! (
44
74
"{}\t {}\t {}\t {}" ,
45
75
index,
@@ -53,6 +83,8 @@ impl SubcommandExecutor for ListArgs {
53
83
. unwrap_or( "ERROR during calculation" . to_string( ) )
54
84
)
55
85
} ) ;
86
+ }
87
+
56
88
Ok ( otp_database)
57
89
}
58
90
}
0 commit comments