@@ -14,10 +14,9 @@ extern crate serde;
1414extern crate serde_json;
1515
1616use std:: error:: Error ;
17- use std:: path:: Path ;
1817use std:: path:: PathBuf ;
1918
20- use chrono:: { DateTime , Datelike , TimeZone , Utc } ;
19+ use chrono:: { DateTime , Utc } ;
2120use clap:: { Parser , Subcommand } ;
2221
2322use aw_client_rust:: blocking:: AwClient ;
@@ -40,7 +39,7 @@ struct Opts {
4039
4140 /// Port of instance to connect to.
4241 #[ clap( long) ]
43- port : Option < String > ,
42+ port : Option < u16 > ,
4443
4544 /// Convenience option for using the default testing host and port.
4645 #[ clap( long) ]
@@ -58,8 +57,8 @@ enum Commands {
5857 /// Pulls remote buckets then pushes local buckets.
5958 Sync {
6059 /// Host(s) to pull from, comma separated. Will pull from all hosts if not specified.
61- #[ clap( long) ]
62- host : Option < String > ,
60+ #[ clap( long, value_parser=parse_list ) ]
61+ host : Option < Vec < String > > ,
6362 } ,
6463
6564 /// Sync subcommand (advanced)
@@ -73,57 +72,64 @@ enum Commands {
7372 /// If not specified, start from beginning.
7473 /// NOTE: might be unstable, as count cannot be used to verify integrity of sync.
7574 /// Format: YYYY-MM-DD
76- #[ clap( long) ]
77- start_date : Option < String > ,
75+ #[ clap( long, value_parser=parse_start_date ) ]
76+ start_date : Option < DateTime < Utc > > ,
7877
7978 /// Specify buckets to sync using a comma-separated list.
8079 /// If not specified, all buckets will be synced.
81- #[ clap( long) ]
82- buckets : Option < String > ,
80+ #[ clap( long, value_parser=parse_list ) ]
81+ buckets : Option < Vec < String > > ,
8382
8483 /// Mode to sync in. Can be "push", "pull", or "both".
8584 /// Defaults to "both".
8685 #[ clap( long, default_value = "both" ) ]
87- mode : String ,
86+ mode : sync :: SyncMode ,
8887
8988 /// Full path to sync directory.
9089 /// If not specified, exit.
9190 #[ clap( long) ]
92- sync_dir : String ,
91+ sync_dir : PathBuf ,
9392
9493 /// Full path to sync db file
9594 /// Useful for syncing buckets from a specific db file in the sync directory.
9695 /// Must be a valid absolute path to a file in the sync directory.
9796 #[ clap( long) ]
98- sync_db : Option < String > ,
97+ sync_db : Option < PathBuf > ,
9998 } ,
10099 /// List buckets and their sync status.
101100 List { } ,
102101}
103102
103+ fn parse_start_date ( arg : & str ) -> Result < DateTime < Utc > , chrono:: ParseError > {
104+ chrono:: NaiveDate :: parse_from_str ( arg, "%Y-%m-%d" )
105+ . map ( |nd| nd. and_time ( chrono:: NaiveTime :: MIN ) . and_utc ( ) )
106+ }
107+
108+ fn parse_list ( arg : & str ) -> Result < Vec < String > , clap:: Error > {
109+ Ok ( arg. split ( ',' ) . map ( |s| s. to_string ( ) ) . collect ( ) )
110+ }
111+
104112fn main ( ) -> Result < ( ) , Box < dyn Error > > {
105113 let opts: Opts = Opts :: parse ( ) ;
106114 let verbose = opts. verbose ;
107115
108116 info ! ( "Started aw-sync..." ) ;
109117
110- aw_server:: logging:: setup_logger ( "aw-sync" , opts. testing , verbose)
111- . expect ( "Failed to setup logging" ) ;
118+ aw_server:: logging:: setup_logger ( "aw-sync" , opts. testing , verbose) ?;
112119
113120 let port = opts
114121 . port
115- . or_else ( || Some ( crate :: util :: get_server_port ( opts . testing ) . ok ( ) ? . to_string ( ) ) )
116- . unwrap ( ) ;
122+ . map ( |a| Ok ( a ) )
123+ . unwrap_or_else ( || util :: get_server_port ( opts . testing ) ) ? ;
117124
118- let client = AwClient :: new ( opts. host . as_str ( ) , port. as_str ( ) , "aw-sync" ) ;
125+ let client = AwClient :: new ( & opts. host , port, "aw-sync" ) ? ;
119126
120- match & opts. command {
127+ match opts. command {
121128 // Perform basic sync
122129 Commands :: Sync { host } => {
123130 // Pull
124131 match host {
125- Some ( host) => {
126- let hosts: Vec < & str > = host. split ( ',' ) . collect ( ) ;
132+ Some ( hosts) => {
127133 for host in hosts. iter ( ) {
128134 info ! ( "Pulling from host: {}" , host) ;
129135 sync_wrapper:: pull ( host, & client) ?;
@@ -137,8 +143,7 @@ fn main() -> Result<(), Box<dyn Error>> {
137143
138144 // Push
139145 info ! ( "Pushing local data" ) ;
140- sync_wrapper:: push ( & client) ?;
141- Ok ( ( ) )
146+ sync_wrapper:: push ( & client)
142147 }
143148 // Perform two-way sync
144149 Commands :: SyncAdvanced {
@@ -148,60 +153,31 @@ fn main() -> Result<(), Box<dyn Error>> {
148153 sync_dir,
149154 sync_db,
150155 } => {
151- let sync_directory = if sync_dir. is_empty ( ) {
152- error ! ( "No sync directory specified, exiting..." ) ;
153- std:: process:: exit ( 1 ) ;
154- } else {
155- Path :: new ( & sync_dir)
156- } ;
157- info ! ( "Using sync dir: {}" , sync_directory. display( ) ) ;
158-
159- if let Some ( sync_db) = & sync_db {
160- info ! ( "Using sync db: {}" , sync_db) ;
156+ if !sync_dir. is_absolute ( ) {
157+ Err ( "Sync dir must be absolute" ) ?
161158 }
162159
163- let start: Option < DateTime < Utc > > = start_date. as_ref ( ) . map ( |date| {
164- println ! ( "{}" , date. clone( ) ) ;
165- chrono:: NaiveDate :: parse_from_str ( & date. clone ( ) , "%Y-%m-%d" )
166- . map ( |nd| {
167- Utc . with_ymd_and_hms ( nd. year ( ) , nd. month ( ) , nd. day ( ) , 0 , 0 , 0 )
168- . single ( )
169- . unwrap ( )
170- } )
171- . expect ( "Date was not on the format YYYY-MM-DD" )
172- } ) ;
173-
174- // Parse comma-separated list
175- let buckets_vec: Option < Vec < String > > = buckets
176- . as_ref ( )
177- . map ( |b| b. split ( ',' ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ;
178-
179- let sync_db: Option < PathBuf > = sync_db. as_ref ( ) . map ( |db| {
180- let db_path = Path :: new ( db) ;
160+ info ! ( "Using sync dir: {}" , & sync_dir. display( ) ) ;
161+
162+ if let Some ( db_path) = & sync_db {
163+ info ! ( "Using sync db: {}" , & db_path. display( ) ) ;
164+
181165 if !db_path. is_absolute ( ) {
182- panic ! ( "Sync db path must be absolute" ) ;
166+ Err ( "Sync db path must be absolute" ) ?
183167 }
184- if !db_path. starts_with ( sync_directory ) {
185- panic ! ( "Sync db path must be in sync directory" ) ;
168+ if !db_path. starts_with ( & sync_dir ) {
169+ Err ( "Sync db path must be in sync directory" ) ?
186170 }
187- db_path. to_path_buf ( )
188- } ) ;
171+ }
189172
190173 let sync_spec = sync:: SyncSpec {
191- path : sync_directory . to_path_buf ( ) ,
174+ path : sync_dir ,
192175 path_db : sync_db,
193- buckets : buckets_vec,
194- start,
195- } ;
196-
197- let mode_enum = match mode. as_str ( ) {
198- "push" => sync:: SyncMode :: Push ,
199- "pull" => sync:: SyncMode :: Pull ,
200- "both" => sync:: SyncMode :: Both ,
201- _ => panic ! ( "Invalid mode" ) ,
176+ buckets,
177+ start : start_date,
202178 } ;
203179
204- sync:: sync_run ( & client, & sync_spec, mode_enum )
180+ sync:: sync_run ( & client, & sync_spec, mode )
205181 }
206182
207183 // List all buckets
0 commit comments