feat(CLI): upload flag parsing

We handle errors gracefully with costum types and minimal amount of
code. Unfortunately, Mime type parsing is very 'flexible', allowing
nonesense types to be passed easily.

Related to #62
This commit is contained in:
Sebastian Thiel
2015-04-15 17:23:01 +02:00
parent 306852d514
commit 9eed4056e5
3 changed files with 64 additions and 6 deletions

View File

@@ -22,7 +22,9 @@
hub_type_name = 'api::' + hub_type(c.schemas, util.canonical_name())
%>\
mod cmn;
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg};
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts};
use std::default::Default;
use std::str::FromStr;
@@ -227,7 +229,23 @@ ${value_unwrap}\
}
}
% endif # handle call parameters
## TODO: parse upload
% if mc.media_params:
let protocol =
% for p in mc.media_params:
% if loop.first:
if \
% else:
} else if \
% endif
${SOPT + cmd_ident(p.protocol)} {
"${p.protocol}"
% endfor # each media param
} else {
unreachable!()
};
let mut input_file = input_file_from_opts(&${SOPT + arg_ident(FILE_ARG[1:-1])}, err);
let mime_type = input_mime_from_opts(&${SOPT + arg_ident(MIME_ARG[1:-1])}, err);
% endif # support upload
if dry_run {
None
} else {

View File

@@ -12,18 +12,18 @@
</%block>
#![feature(plugin, exit_status)]
#![plugin(docopt_macros)]
#![allow(unused_variables, unused_imports, dead_code, unsed_mut)]
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
extern crate docopt;
extern crate yup_oauth2 as oauth2;
extern crate rustc_serialize;
extern crate serde;
extern crate hyper;
extern crate mime;
extern crate ${to_extern_crate_name(library_to_crate_name(library_name(name, version), make.depends_on_suffix))} as api;
use std::io;
use std::env;
use std::io::Write;
use std::io::{self, Write};
${docopt.new(c)}\

View File

@@ -1,5 +1,6 @@
use oauth2::{ApplicationSecret, ConsoleApplicationSecret, TokenStorage, Token};
use rustc_serialize::json;
use mime::Mime;
use std::fs;
use std::env;
@@ -31,6 +32,26 @@ pub fn parse_kv_arg<'a>(kv: &'a str, err: &mut InvalidOptionsError)
}
}
pub fn input_file_from_opts(file_path: &str, err: &mut InvalidOptionsError) -> Option<fs::File> {
match fs::File::open(file_path) {
Ok(f) => Some(f),
Err(io_err) => {
err.issues.push(CLIError::Input(InputError::IOError((file_path.to_string(), io_err))));
None
}
}
}
pub fn input_mime_from_opts(mime: &str, err: &mut InvalidOptionsError) -> Option<Mime> {
match mime.parse() {
Ok(m) => Some(m),
Err(_) => {
err.issues.push(CLIError::Input(InputError::Mime(mime.to_string())));
None
}
}
}
// May panic if we can't open the file - this is anticipated, we can't currently communicate this
// kind of error: TODO: fix this architecture :)
pub fn writer_from_opts(flag: bool, arg: &str) -> Box<Write> {
@@ -138,18 +159,37 @@ impl fmt::Display for ConfigurationError {
}
}
#[derive(Debug)]
pub enum InputError {
IOError((String, io::Error)),
Mime(String),
}
impl fmt::Display for InputError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
InputError::IOError((ref file_path, ref io_err))
=> writeln!(f, "Failed to open '{}' for reading with error: {}", file_path, io_err),
InputError::Mime(ref mime)
=> writeln!(f, "'{}' is not a known mime-type", mime),
}
}
}
#[derive(Debug)]
pub enum CLIError {
Configuration(ConfigurationError),
ParseError((&'static str, &'static str, String, String)),
UnknownParameter(String),
InvalidKeyValueSyntax(String),
Input(InputError),
}
impl fmt::Display for CLIError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
CLIError::Configuration(ref err) => writeln!(f, "Configuration -> {}", err),
CLIError::Configuration(ref err) => write!(f, "Configuration -> {}", err),
CLIError::Input(ref err) => write!(f, "Input -> {}", err),
CLIError::ParseError((arg_name, type_name, ref value, ref err_desc))
=> writeln!(f, "Failed to parse argument '{}' with value '{}' as {} with error: {}",
arg_name, value, type_name, err_desc),