Implement history command base

This commit is contained in:
timvisee 2018-04-26 10:49:29 +02:00
parent 0b03734650
commit 1a50b7a569
No known key found for this signature in database
GPG key ID: 109CBA0BF74036C2
10 changed files with 129 additions and 1 deletions

62
cli/src/action/history.rs Normal file
View file

@ -0,0 +1,62 @@
use clap::ArgMatches;
use cmd::matcher::{
Matcher,
history::HistoryMatcher,
main::MainMatcher,
};
use error::ActionError;
use history::{
History as HistoryManager,
LoadError as HistoryLoadError,
};
/// A history action.
pub struct History<'a> {
cmd_matches: &'a ArgMatches<'a>,
}
impl<'a> History<'a> {
/// Construct a new history action.
pub fn new(cmd_matches: &'a ArgMatches<'a>) -> Self {
Self {
cmd_matches,
}
}
/// Invoke the history action.
// TODO: create a trait for this method
pub fn invoke(&self) -> Result<(), ActionError> {
// Create the command matchers
let matcher_main = MainMatcher::with(self.cmd_matches).unwrap();
let _matcher_history = HistoryMatcher::with(self.cmd_matches).unwrap();
// Get the history path, make sure it exists
let history_path = matcher_main.history();
if !history_path.is_file() {
return Ok(());
}
// History
let history = HistoryManager::load(history_path)?;
for file in history.files() {
println!("- File ID: {}", file.id());
}
Ok(())
}
}
#[derive(Debug, Fail)]
pub enum Error {
/// Failed to load the history.
#[fail(display = "Failed to load file history")]
Load(#[cause] HistoryLoadError),
}
impl From<HistoryLoadError> for ActionError {
fn from(err: HistoryLoadError) -> ActionError {
ActionError::History(Error::Load(err))
}
}

View file

@ -1,6 +1,7 @@
pub mod delete;
pub mod download;
pub mod exists;
pub mod history;
pub mod info;
pub mod params;
pub mod password;

View file

@ -0,0 +1,15 @@
use clap::{App, SubCommand};
/// The history command definition.
pub struct CmdHistory;
impl CmdHistory {
pub fn build<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name("history")
.about("View file history")
.visible_alias("h")
.alias("his")
.alias("list")
.alias("ls")
}
}

View file

@ -1,6 +1,7 @@
pub mod delete;
pub mod download;
pub mod exists;
pub mod history;
pub mod info;
pub mod params;
pub mod password;
@ -10,6 +11,7 @@ pub mod upload;
pub use self::delete::CmdDelete;
pub use self::download::CmdDownload;
pub use self::exists::CmdExists;
pub use self::history::CmdHistory;
pub use self::info::CmdInfo;
pub use self::params::CmdParams;
pub use self::password::CmdPassword;

View file

@ -7,6 +7,7 @@ use super::matcher::{
DeleteMatcher,
DownloadMatcher,
ExistsMatcher,
HistoryMatcher,
InfoMatcher,
Matcher,
ParamsMatcher,
@ -17,6 +18,7 @@ use super::cmd::{
CmdDelete,
CmdDownload,
CmdExists,
CmdHistory,
CmdInfo,
CmdParams,
CmdPassword,
@ -92,6 +94,7 @@ impl<'a: 'b, 'b> Handler<'a> {
.subcommand(CmdDelete::build())
.subcommand(CmdDownload::build().display_order(2))
.subcommand(CmdExists::build())
.subcommand(CmdHistory::build())
.subcommand(CmdInfo::build())
.subcommand(CmdParams::build())
.subcommand(CmdPassword::build())
@ -132,6 +135,11 @@ impl<'a: 'b, 'b> Handler<'a> {
ExistsMatcher::with(&self.matches)
}
/// Get the history sub command, if matched.
pub fn history(&'a self) -> Option<HistoryMatcher> {
HistoryMatcher::with(&self.matches)
}
/// Get the info matcher, if that subcommand is entered.
pub fn info(&'a self) -> Option<InfoMatcher> {
InfoMatcher::with(&self.matches)

View file

@ -0,0 +1,20 @@
use clap::ArgMatches;
use super::Matcher;
/// The history command matcher.
pub struct HistoryMatcher<'a> {
#[allow(unused)]
matches: &'a ArgMatches<'a>,
}
impl<'a> Matcher<'a> for HistoryMatcher<'a> {
fn with(matches: &'a ArgMatches) -> Option<Self> {
matches.subcommand_matches("history")
.map(|matches|
HistoryMatcher {
matches,
}
)
}
}

View file

@ -1,6 +1,7 @@
pub mod delete;
pub mod download;
pub mod exists;
pub mod history;
pub mod info;
pub mod main;
pub mod params;
@ -11,6 +12,7 @@ pub mod upload;
pub use self::delete::DeleteMatcher;
pub use self::download::DownloadMatcher;
pub use self::exists::ExistsMatcher;
pub use self::history::HistoryMatcher;
pub use self::info::InfoMatcher;
pub use self::main::MainMatcher;
pub use self::params::ParamsMatcher;

View file

@ -6,6 +6,7 @@ use ffsend_api::action::upload::Error as UploadError;
use ffsend_api::file::remote_file::FileParseError;
use action::download::Error as CliDownloadError;
use action::history::Error as CliHistoryError;
use action::info::Error as CliInfoError;
#[derive(Fail, Debug)]
@ -47,6 +48,10 @@ pub enum ActionError {
#[fail(display = "Failed to check whether the file exists")]
Exists(#[cause] ExistsError),
/// An error occurred while processing the file history.
#[fail(display = "Failed to process the history")]
History(#[cause] CliHistoryError),
/// An error occurred while invoking the info action.
#[fail(display = "Failed to fetch file info")]
Info(#[cause] CliInfoError),
@ -82,6 +87,12 @@ impl From<ExistsError> for ActionError {
}
}
impl From<CliHistoryError> for ActionError {
fn from(err: CliHistoryError) -> ActionError {
ActionError::History(err)
}
}
impl From<ParamsError> for ActionError {
fn from(err: ParamsError) -> ActionError {
ActionError::Params(err)

View file

@ -26,6 +26,7 @@ mod util;
use action::delete::Delete;
use action::download::Download;
use action::exists::Exists;
use action::history::History;
use action::info::Info;
use action::params::Params;
use action::password::Password;
@ -68,6 +69,12 @@ fn invoke_action(handler: &Handler) -> Result<(), Error> {
.map_err(|err| err.into());
}
// Match the history command
if handler.history().is_some() {
return History::new(handler.matches()).invoke()
.map_err(|err| err.into());
}
// Match the info command
if handler.info().is_some() {
return Info::new(handler.matches()).invoke()

View file

@ -26,7 +26,7 @@ use cmd::matcher::MainMatcher;
/// Print a success message.
pub fn print_success(msg: &str) {
println!("{}", msg.green());
eprintln!("{}", msg.green());
}
/// Print the given error in a proper format for the user,