3
3
//! This application provides a command-line interface to interact with
4
4
//! Toggl Track's time tracking service.
5
5
6
- use crate :: cli:: { Clients , Options , SubCommand , TimeEntries } ;
6
+ use crate :: cli:: { Clients , Format , Options , SubCommand , TimeEntries } ;
7
7
use crate :: config:: init_settings_file;
8
- use clap:: Parser ;
8
+ use clap:: { CommandFactory , Parser } ;
9
9
use cli:: { Projects , Reports , Settings } ;
10
10
use client:: init_client;
11
11
use report_client:: init_report_client;
@@ -27,95 +27,151 @@ mod client_tests;
27
27
28
28
fn main ( ) -> anyhow:: Result < ( ) > {
29
29
let options = Options :: parse ( ) ;
30
+
31
+ // Handle completion generation if requested
32
+ if let Some ( shell) = options. completions {
33
+ let mut cmd = Options :: command ( ) ;
34
+ cli:: print_completions ( shell, & mut cmd) ;
35
+ return Ok ( ( ) ) ;
36
+ }
37
+
30
38
let format = options. format ;
31
39
let debug = options. debug ;
32
40
33
- match options. subcommand {
41
+ if let Some ( subcommand) = options. subcommand {
42
+ execute_subcommand ( subcommand, debug, & format) ?;
43
+ } else {
44
+ eprintln ! (
45
+ "Error: A subcommand is required when not generating completions"
46
+ ) ;
47
+ std:: process:: exit ( 1 ) ;
48
+ }
49
+
50
+ Ok ( ( ) )
51
+ }
52
+
53
+ fn execute_subcommand (
54
+ subcommand : SubCommand ,
55
+ debug : bool ,
56
+ format : & Format ,
57
+ ) -> anyhow:: Result < ( ) > {
58
+ match subcommand {
34
59
SubCommand :: Init => init_settings_file ( ) ?,
35
- SubCommand :: Settings ( action) => match action {
36
- Settings :: Init => init_settings_file ( ) ?,
37
- } ,
38
- SubCommand :: Projects ( action) => match action {
39
- Projects :: List ( list_projects) => {
40
- let client = init_client ( ) ?;
41
-
42
- commands:: projects:: list (
43
- debug,
44
- list_projects. include_archived ,
45
- & format,
46
- & client,
47
- ) ?;
48
- }
49
- } ,
50
- SubCommand :: Workspaces ( _action) => {
60
+ SubCommand :: Settings ( action) => handle_settings ( action) ?,
61
+ SubCommand :: Projects ( action) => handle_projects ( action, debug, format) ?,
62
+ SubCommand :: Workspaces ( _action) => handle_workspaces ( debug, format) ?,
63
+ SubCommand :: TimeEntries ( action) => {
64
+ handle_time_entries ( action, debug, format) ?;
65
+ }
66
+ SubCommand :: Clients ( action) => handle_clients ( action, debug, format) ?,
67
+ SubCommand :: Reports ( action) => handle_reports ( action, debug) ?,
68
+ }
69
+ Ok ( ( ) )
70
+ }
71
+
72
+ fn handle_settings ( action : Settings ) -> anyhow:: Result < ( ) > {
73
+ match action {
74
+ Settings :: Init => init_settings_file ( ) ?,
75
+ }
76
+ Ok ( ( ) )
77
+ }
78
+
79
+ fn handle_projects (
80
+ action : Projects ,
81
+ debug : bool ,
82
+ format : & Format ,
83
+ ) -> anyhow:: Result < ( ) > {
84
+ match action {
85
+ Projects :: List ( list_projects) => {
51
86
let client = init_client ( ) ?;
87
+ commands:: projects:: list (
88
+ debug,
89
+ list_projects. include_archived ,
90
+ format,
91
+ & client,
92
+ ) ?;
93
+ }
94
+ }
95
+ Ok ( ( ) )
96
+ }
52
97
53
- commands:: workspaces:: list ( debug, & format, & client) ?;
98
+ fn handle_workspaces ( debug : bool , format : & Format ) -> anyhow:: Result < ( ) > {
99
+ let client = init_client ( ) ?;
100
+ commands:: workspaces:: list ( debug, format, & client) ?;
101
+ Ok ( ( ) )
102
+ }
103
+
104
+ fn handle_time_entries (
105
+ action : TimeEntries ,
106
+ debug : bool ,
107
+ format : & Format ,
108
+ ) -> anyhow:: Result < ( ) > {
109
+ let client = init_client ( ) ?;
110
+
111
+ match action {
112
+ TimeEntries :: Create ( time_entry) => {
113
+ commands:: time_entries:: create ( debug, format, & time_entry, & client) ?;
114
+ }
115
+ TimeEntries :: List ( list_time_entries) => {
116
+ commands:: time_entries:: list (
117
+ debug,
118
+ format,
119
+ & list_time_entries. range ,
120
+ list_time_entries. missing ,
121
+ & client,
122
+ ) ?;
54
123
}
124
+ TimeEntries :: Start ( time_entry) => {
125
+ commands:: time_entries:: start ( debug, format, & time_entry, & client) ?;
126
+ }
127
+ TimeEntries :: Stop ( time_entry) => {
128
+ commands:: time_entries:: stop ( debug, format, & time_entry, & client) ?;
129
+ }
130
+ TimeEntries :: Delete ( time_entry) => {
131
+ commands:: time_entries:: delete ( debug, format, & time_entry, & client) ?;
132
+ }
133
+ TimeEntries :: Details ( time_entry) => {
134
+ commands:: time_entries:: details ( debug, format, & time_entry, & client) ?;
135
+ }
136
+ }
137
+ Ok ( ( ) )
138
+ }
139
+
140
+ fn handle_clients (
141
+ action : Clients ,
142
+ debug : bool ,
143
+ format : & Format ,
144
+ ) -> anyhow:: Result < ( ) > {
145
+ let client = init_client ( ) ?;
55
146
56
- SubCommand :: TimeEntries ( action) => match action {
57
- TimeEntries :: Create ( time_entry) => {
58
- let client = init_client ( ) ?;
59
- commands:: time_entries:: create ( debug, & format, & time_entry, & client) ?;
60
- }
61
- TimeEntries :: List ( list_time_entries) => {
62
- let client = init_client ( ) ?;
63
- commands:: time_entries:: list (
64
- debug,
65
- & format,
66
- & list_time_entries. range ,
67
- list_time_entries. missing ,
68
- & client,
69
- ) ?;
70
- }
71
- TimeEntries :: Start ( time_entry) => {
72
- let client = init_client ( ) ?;
73
- commands:: time_entries:: start ( debug, & format, & time_entry, & client) ?;
74
- }
75
- TimeEntries :: Stop ( time_entry) => {
76
- let client = init_client ( ) ?;
77
- commands:: time_entries:: stop ( debug, & format, & time_entry, & client) ?;
78
- }
79
- TimeEntries :: Delete ( time_entry) => {
80
- let client = init_client ( ) ?;
81
- commands:: time_entries:: delete ( debug, & format, & time_entry, & client) ?;
82
- }
83
- TimeEntries :: Details ( time_entry) => {
84
- let client = init_client ( ) ?;
85
- commands:: time_entries:: details ( debug, & format, & time_entry, & client) ?;
86
- }
87
- } ,
88
-
89
- SubCommand :: Clients ( action) => match action {
90
- Clients :: Create ( create_client) => {
91
- let client = init_client ( ) ?;
92
- commands:: clients:: create ( debug, & format, & create_client, & client) ?;
93
- }
94
- Clients :: List ( list_clients) => {
95
- let client = init_client ( ) ?;
96
- commands:: clients:: list (
97
- debug,
98
- list_clients. include_archived ,
99
- & format,
100
- & client,
101
- ) ?;
102
- }
103
- } ,
104
-
105
- SubCommand :: Reports ( action) => match action {
106
- Reports :: Detailed ( detailed) => {
107
- let client = init_client ( ) ?;
108
- let report_client = init_report_client ( ) ?;
109
-
110
- commands:: reports:: detailed (
111
- debug,
112
- & client,
113
- & detailed. range ,
114
- & report_client,
115
- ) ?;
116
- }
117
- } ,
147
+ match action {
148
+ Clients :: Create ( create_client) => {
149
+ commands:: clients:: create ( debug, format, & create_client, & client) ?;
150
+ }
151
+ Clients :: List ( list_clients) => {
152
+ commands:: clients:: list (
153
+ debug,
154
+ list_clients. include_archived ,
155
+ format,
156
+ & client,
157
+ ) ?;
158
+ }
118
159
}
160
+ Ok ( ( ) )
161
+ }
119
162
163
+ fn handle_reports ( action : Reports , debug : bool ) -> anyhow:: Result < ( ) > {
164
+ match action {
165
+ Reports :: Detailed ( detailed) => {
166
+ let client = init_client ( ) ?;
167
+ let report_client = init_report_client ( ) ?;
168
+ commands:: reports:: detailed (
169
+ debug,
170
+ & client,
171
+ & detailed. range ,
172
+ & report_client,
173
+ ) ?;
174
+ }
175
+ }
120
176
Ok ( ( ) )
121
177
}
0 commit comments