summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cli.rs18
-rw-r--r--src/cmd/sql.rs59
-rw-r--r--src/cmd/sync.rs45
3 files changed, 64 insertions, 58 deletions
diff --git a/src/cli.rs b/src/cli.rs
index 1049b64..b5ac878 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -2,27 +2,23 @@ use cmd;
const _DUMMY_DEPENDENCY: &'static str = include_str!("../Cargo.toml");
-enum Command {
- Sync(cmd::sync::Options),
- SQL(cmd::sql::Options),
+pub trait Command {
+ fn run(&self) -> failure::Fallible<()>;
}
pub fn run() -> failure::Fallible<()> {
- match get_options()? {
- Command::Sync(options) => cmd::sync::run(&options),
- Command::SQL(options) => cmd::sql::run(&options),
- }
+ get_command()?.run()
}
-fn get_options() -> failure::Fallible<Command> {
+fn get_command() -> failure::Fallible<Box<Command>> {
let matches = app_from_crate!()
.subcommand(cmd::sync::subcommand())
.subcommand(cmd::sql::subcommand())
.get_matches();
- let command = match matches.subcommand() {
- ("sync", Some(matches)) => Command::Sync(cmd::sync::options(matches)),
- ("sql", Some(matches)) => Command::SQL(cmd::sql::options(matches)),
+ let command: Box<Command> = match matches.subcommand() {
+ ("sync", Some(matches)) => Box::new(cmd::sync::Command::new(matches)),
+ ("sql", Some(matches)) => Box::new(cmd::sql::Command::new(matches)),
(name, Some(_)) => bail!("unknown subcommand: {}", name),
(_, None) => bail!("no subcommand given"),
diff --git a/src/cmd/sql.rs b/src/cmd/sql.rs
index b6a77cf..f0dd4b0 100644
--- a/src/cmd/sql.rs
+++ b/src/cmd/sql.rs
@@ -1,9 +1,10 @@
+use cli;
use db;
use paths;
use clap;
-pub struct Options {
+pub struct Command {
query: String,
tsv: bool,
}
@@ -23,37 +24,41 @@ pub fn subcommand<'a, 'b>() -> clap::App<'a, 'b> {
)
}
-pub fn options<'a>(matches: &clap::ArgMatches<'a>) -> Options {
- Options {
- query: matches.value_of("query").unwrap().to_string(),
- tsv: matches.is_present("tsv"),
+impl Command {
+ pub fn new<'a>(matches: &clap::ArgMatches<'a>) -> Command {
+ Command {
+ query: matches.value_of("query").unwrap().to_string(),
+ tsv: matches.is_present("tsv"),
+ }
}
}
-pub fn run(options: &Options) -> failure::Fallible<()> {
- let db = db::DB::new(&paths::db_path()?)?;
-
- let rows_cell = std::cell::Cell::new(Some(vec![]));
- let cols = db.query(&options.query, |row| {
- let display_row: Vec<String> = (0..row.column_count())
- .map(|i| row.get_raw(i))
- .map(|v| format_value(&v))
- .collect();
- let mut rows = rows_cell.replace(None).unwrap();
- rows.push(display_row);
- rows_cell.replace(Some(rows));
- })?;
-
- let rows = rows_cell.into_inner().unwrap();
+impl cli::Command for Command {
+ fn run(&self) -> failure::Fallible<()> {
+ let db = db::DB::new(&paths::db_path()?)?;
+
+ let rows_cell = std::cell::Cell::new(Some(vec![]));
+ let cols = db.query(&self.query, |row| {
+ let display_row: Vec<String> = (0..row.column_count())
+ .map(|i| row.get_raw(i))
+ .map(|v| format_value(&v))
+ .collect();
+ let mut rows = rows_cell.replace(None).unwrap();
+ rows.push(display_row);
+ rows_cell.replace(Some(rows));
+ })?;
+
+ let rows = rows_cell.into_inner().unwrap();
+
+ if self.tsv {
+ print_tsv(&rows);
+ }
+ else {
+ print_table(&cols, &rows);
+ }
- if options.tsv {
- print_tsv(&rows);
- }
- else {
- print_table(&cols, &rows);
+ Ok(())
}
-
- Ok(())
}
fn print_table(cols: &[String], rows: &[Vec<String>]) {
diff --git a/src/cmd/sync.rs b/src/cmd/sync.rs
index 9e09289..3dc7ba8 100644
--- a/src/cmd/sync.rs
+++ b/src/cmd/sync.rs
@@ -1,10 +1,11 @@
+use cli;
use db;
use lastfm;
use paths;
use clap;
-pub struct Options {
+pub struct Command {
username: String,
}
@@ -18,31 +19,35 @@ pub fn subcommand<'a, 'b>() -> clap::App<'a, 'b> {
)
}
-pub fn options<'a>(matches: &clap::ArgMatches<'a>) -> Options {
- Options {
- username: matches.value_of("username").unwrap().to_string(),
+impl Command {
+ pub fn new<'a>(matches: &clap::ArgMatches<'a>) -> Command {
+ Command {
+ username: matches.value_of("username").unwrap().to_string(),
+ }
}
}
-pub fn run(options: &Options) -> failure::Fallible<()> {
- let db = db::DB::new(&paths::db_path()?)?;
- let lastfm = lastfm::LastFMClient::new(&options.username)?;
+impl cli::Command for Command {
+ fn run(&self) -> failure::Fallible<()> {
+ let db = db::DB::new(&paths::db_path()?)?;
+ let lastfm = lastfm::LastFMClient::new(&self.username)?;
- let from = db.most_recent_timestamp()?.map(|x| x + 1);
- let to_fetch = lastfm.track_count(from)?;
+ let from = db.most_recent_timestamp()?.map(|x| x + 1);
+ let to_fetch = lastfm.track_count(from)?;
- if to_fetch > 0 {
- let bar = indicatif::ProgressBar::new(to_fetch);
- bar.set_style(
- indicatif::ProgressStyle::default_bar()
- .progress_chars("=> ")
- .template("Downloading {pos}/{len} tracks...\n{percent:>3}% [{wide_bar}] {eta:5}")
- );
+ if to_fetch > 0 {
+ let bar = indicatif::ProgressBar::new(to_fetch);
+ bar.set_style(
+ indicatif::ProgressStyle::default_bar()
+ .progress_chars("=> ")
+ .template("Downloading {pos}/{len} tracks...\n{percent:>3}% [{wide_bar}] {eta:5}")
+ );
- db.insert_tracks(bar.wrap_iter(lastfm.tracks(from)))?;
+ db.insert_tracks(bar.wrap_iter(lastfm.tracks(from)))?;
- bar.finish_with_message("done");
- }
+ bar.finish_with_message("done");
+ }
- Ok(())
+ Ok(())
+ }
}