mirror of
https://github.com/timvisee/ffsend.git
synced 2025-10-03 17:49:15 +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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"openssl 0.10.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -8,6 +8,7 @@ base64 = "0.9"
|
||||||
clap = "2.31"
|
clap = "2.31"
|
||||||
hkdf = "0.3"
|
hkdf = "0.3"
|
||||||
hyper = "0.11.9" # same as reqwest
|
hyper = "0.11.9" # same as reqwest
|
||||||
|
lazy_static = "1.0"
|
||||||
mime_guess = "2.0.0-alpha.2"
|
mime_guess = "2.0.0-alpha.2"
|
||||||
open = "1"
|
open = "1"
|
||||||
openssl = "0.10"
|
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 hyper;
|
||||||
|
extern crate lazy_static;
|
||||||
extern crate mime_guess;
|
extern crate mime_guess;
|
||||||
extern crate open;
|
extern crate open;
|
||||||
extern crate openssl;
|
extern crate openssl;
|
||||||
|
@ -8,7 +9,7 @@ extern crate reqwest;
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod arg_handler;
|
mod cmd;
|
||||||
mod b64;
|
mod b64;
|
||||||
mod crypto;
|
mod crypto;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
|
@ -24,17 +25,41 @@ use reqwest::header::Authorization;
|
||||||
use reqwest::mime::APPLICATION_OCTET_STREAM;
|
use reqwest::mime::APPLICATION_OCTET_STREAM;
|
||||||
use reqwest::multipart::Part;
|
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 crypto::{derive_auth_key, derive_file_key, derive_meta_key};
|
||||||
use metadata::{Metadata, XFileMetadata};
|
use metadata::{Metadata, XFileMetadata};
|
||||||
use reader::EncryptedFileReaderTagged;
|
use reader::EncryptedFileReaderTagged;
|
||||||
|
|
||||||
|
/// Application entrypoint.
|
||||||
fn main() {
|
fn main() {
|
||||||
// Parse CLI arguments
|
// 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
|
// Get the path
|
||||||
let path = Path::new(arg_handler.file());
|
let path = Path::new(cmd_upload.file());
|
||||||
|
|
||||||
// Make sure the path is a file
|
// Make sure the path is a file
|
||||||
if !path.is_file() {
|
if !path.is_file() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue