mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-03 01:29:16 +02:00
Improve CLI argument handling for subcommand use
This commit is contained in:
parent
188b0cb2e1
commit
fb7fd69400
7 changed files with 110 additions and 45 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -175,6 +175,7 @@ dependencies = [
|
|||
"clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hkdf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.11.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -8,6 +8,7 @@ base64 = "0.9"
|
|||
clap = "2.31"
|
||||
hkdf = "0.3"
|
||||
hyper = "0.11.9" # same as reqwest
|
||||
lazy_static = "1.0"
|
||||
mime_guess = "2.0.0-alpha.2"
|
||||
open = "1"
|
||||
openssl = "0.10"
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
extern crate clap;
|
||||
|
||||
use self::clap::{Arg, ArgMatches, App};
|
||||
|
||||
use app::*;
|
||||
|
||||
/// CLI argument handler.
|
||||
pub struct ArgHandler<'a> {
|
||||
matches: ArgMatches<'a>,
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> ArgHandler<'a> {
|
||||
/// Parse CLI arguments.
|
||||
pub fn parse() -> ArgHandler<'a> {
|
||||
// Handle/parse arguments
|
||||
let matches = App::new(APP_NAME)
|
||||
.version(APP_VERSION)
|
||||
.author(APP_AUTHOR)
|
||||
.about(APP_ABOUT)
|
||||
.arg(Arg::with_name("file")
|
||||
.short("f")
|
||||
.long("file")
|
||||
.value_name("PATH")
|
||||
.help("The file to upload")
|
||||
.required(true)
|
||||
.multiple(false))
|
||||
.get_matches();
|
||||
|
||||
// Instantiate
|
||||
ArgHandler {
|
||||
matches,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the selected file to upload.
|
||||
pub fn file(&'a self) -> &'a str {
|
||||
self.matches.value_of("file")
|
||||
.expect("please specify a file to upload")
|
||||
}
|
||||
}
|
||||
|
37
src/cmd/cmd_upload.rs
Normal file
37
src/cmd/cmd_upload.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use super::clap::{App, Arg, ArgMatches, SubCommand};
|
||||
|
||||
/// The sub command name.
|
||||
const CMD_NAME: &'static str = "upload";
|
||||
|
||||
/// The upload command.
|
||||
pub struct CmdUpload<'a> {
|
||||
matches: &'a ArgMatches<'a>,
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> CmdUpload<'a> {
|
||||
/// Build the sub command definition.
|
||||
pub fn build<'y, 'z>() -> App<'y, 'z> {
|
||||
SubCommand::with_name(CMD_NAME)
|
||||
.about("Upload files")
|
||||
.visible_alias("u")
|
||||
.visible_alias("up")
|
||||
.arg(
|
||||
Arg::with_name("FILE")
|
||||
.help("The file to upload")
|
||||
.required(true)
|
||||
.multiple(false)
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse CLI arguments, from the given parent command matches.
|
||||
pub fn parse(parent: &'a ArgMatches<'a>) -> Option<CmdUpload<'a>> {
|
||||
parent.subcommand_matches(CMD_NAME)
|
||||
.map(|matches| CmdUpload { matches })
|
||||
}
|
||||
|
||||
/// Get the selected file to upload.
|
||||
pub fn file(&'a self) -> &'a str {
|
||||
self.matches.value_of("FILE")
|
||||
.expect("please specify a file to upload")
|
||||
}
|
||||
}
|
35
src/cmd/handler.rs
Normal file
35
src/cmd/handler.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use super::clap::{App, ArgMatches};
|
||||
|
||||
use app::*;
|
||||
|
||||
use super::cmd_upload::CmdUpload;
|
||||
|
||||
/// CLI argument handler.
|
||||
pub struct Handler<'a> {
|
||||
/// The CLI matches.
|
||||
matches: ArgMatches<'a>,
|
||||
}
|
||||
|
||||
impl<'a: 'b, 'b> Handler<'a> {
|
||||
/// Build the application CLI definition.
|
||||
pub fn build() -> App<'a, 'b> {
|
||||
App::new(APP_NAME)
|
||||
.version(APP_VERSION)
|
||||
.author(APP_AUTHOR)
|
||||
.about(APP_ABOUT)
|
||||
.subcommand(CmdUpload::build().display_order(1))
|
||||
}
|
||||
|
||||
/// Parse CLI arguments.
|
||||
pub fn parse() -> Handler<'a> {
|
||||
// Build the application CLI definition, get the matches
|
||||
Handler {
|
||||
matches: Handler::build().get_matches(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the upload sub command, if matched.
|
||||
pub fn upload(&'a self) -> Option<CmdUpload<'a>> {
|
||||
CmdUpload::parse(&self.matches)
|
||||
}
|
||||
}
|
7
src/cmd/mod.rs
Normal file
7
src/cmd/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
extern crate clap;
|
||||
|
||||
pub mod cmd_upload;
|
||||
pub mod handler;
|
||||
|
||||
// Reexport modules
|
||||
pub use self::handler::Handler;
|
33
src/main.rs
33
src/main.rs
|
@ -1,4 +1,5 @@
|
|||
extern crate hyper;
|
||||
extern crate lazy_static;
|
||||
extern crate mime_guess;
|
||||
extern crate open;
|
||||
extern crate openssl;
|
||||
|
@ -8,7 +9,7 @@ extern crate reqwest;
|
|||
extern crate serde_derive;
|
||||
|
||||
mod app;
|
||||
mod arg_handler;
|
||||
mod cmd;
|
||||
mod b64;
|
||||
mod crypto;
|
||||
mod metadata;
|
||||
|
@ -24,17 +25,41 @@ use reqwest::header::Authorization;
|
|||
use reqwest::mime::APPLICATION_OCTET_STREAM;
|
||||
use reqwest::multipart::Part;
|
||||
|
||||
use arg_handler::ArgHandler;
|
||||
use cmd::Handler;
|
||||
use cmd::cmd_upload::CmdUpload;
|
||||
use crypto::{derive_auth_key, derive_file_key, derive_meta_key};
|
||||
use metadata::{Metadata, XFileMetadata};
|
||||
use reader::EncryptedFileReaderTagged;
|
||||
|
||||
/// Application entrypoint.
|
||||
fn main() {
|
||||
// Parse CLI arguments
|
||||
let arg_handler = ArgHandler::parse();
|
||||
let cmd_handler = Handler::parse();
|
||||
|
||||
// Invoke the proper action
|
||||
invoke_action(&cmd_handler);
|
||||
}
|
||||
|
||||
/// Invoke the proper action based on the CLI input.
|
||||
///
|
||||
/// If no proper action is selected, the program will quit with an error
|
||||
/// message.
|
||||
fn invoke_action(handler: &Handler) {
|
||||
// Match the upload command
|
||||
if let Some(cmd) = handler.upload() {
|
||||
return action_upload(&cmd);
|
||||
}
|
||||
|
||||
// No subcommand was selected, show general help
|
||||
Handler::build()
|
||||
.print_help()
|
||||
.expect("failed to print command help");
|
||||
}
|
||||
|
||||
/// The upload action.
|
||||
fn action_upload(cmd_upload: &CmdUpload) {
|
||||
// Get the path
|
||||
let path = Path::new(arg_handler.file());
|
||||
let path = Path::new(cmd_upload.file());
|
||||
|
||||
// Make sure the path is a file
|
||||
if !path.is_file() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue