Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9eed405

Browse files
committed
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
1 parent 306852d commit 9eed405

3 files changed

Lines changed: 64 additions & 6 deletions

File tree

src/mako/cli/lib/engine.mako

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
hub_type_name = 'api::' + hub_type(c.schemas, util.canonical_name())
2323
%>\
2424
mod cmn;
25-
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg};
25+
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
26+
input_file_from_opts, input_mime_from_opts};
27+
2628
use std::default::Default;
2729
use std::str::FromStr;
2830
@@ -227,7 +229,23 @@ ${value_unwrap}\
227229
}
228230
}
229231
% endif # handle call parameters
230-
## TODO: parse upload
232+
% if mc.media_params:
233+
let protocol =
234+
% for p in mc.media_params:
235+
% if loop.first:
236+
if \
237+
% else:
238+
} else if \
239+
% endif
240+
${SOPT + cmd_ident(p.protocol)} {
241+
"${p.protocol}"
242+
% endfor # each media param
243+
} else {
244+
unreachable!()
245+
};
246+
let mut input_file = input_file_from_opts(&${SOPT + arg_ident(FILE_ARG[1:-1])}, err);
247+
let mime_type = input_mime_from_opts(&${SOPT + arg_ident(MIME_ARG[1:-1])}, err);
248+
% endif # support upload
231249
if dry_run {
232250
None
233251
} else {

src/mako/cli/main.rs.mako

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@
1212
</%block>
1313
#![feature(plugin, exit_status)]
1414
#![plugin(docopt_macros)]
15-
#![allow(unused_variables, unused_imports, dead_code, unsed_mut)]
15+
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
1616

1717
extern crate docopt;
1818
extern crate yup_oauth2 as oauth2;
1919
extern crate rustc_serialize;
2020
extern crate serde;
2121
extern crate hyper;
22+
extern crate mime;
2223
extern crate ${to_extern_crate_name(library_to_crate_name(library_name(name, version), make.depends_on_suffix))} as api;
2324

24-
use std::io;
2525
use std::env;
26-
use std::io::Write;
26+
use std::io::{self, Write};
2727

2828
${docopt.new(c)}\
2929

src/rust/cli/cmn.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use oauth2::{ApplicationSecret, ConsoleApplicationSecret, TokenStorage, Token};
22
use rustc_serialize::json;
3+
use mime::Mime;
34

45
use std::fs;
56
use std::env;
@@ -31,6 +32,26 @@ pub fn parse_kv_arg<'a>(kv: &'a str, err: &mut InvalidOptionsError)
3132
}
3233
}
3334

35+
pub fn input_file_from_opts(file_path: &str, err: &mut InvalidOptionsError) -> Option<fs::File> {
36+
match fs::File::open(file_path) {
37+
Ok(f) => Some(f),
38+
Err(io_err) => {
39+
err.issues.push(CLIError::Input(InputError::IOError((file_path.to_string(), io_err))));
40+
None
41+
}
42+
}
43+
}
44+
45+
pub fn input_mime_from_opts(mime: &str, err: &mut InvalidOptionsError) -> Option<Mime> {
46+
match mime.parse() {
47+
Ok(m) => Some(m),
48+
Err(_) => {
49+
err.issues.push(CLIError::Input(InputError::Mime(mime.to_string())));
50+
None
51+
}
52+
}
53+
}
54+
3455
// May panic if we can't open the file - this is anticipated, we can't currently communicate this
3556
// kind of error: TODO: fix this architecture :)
3657
pub fn writer_from_opts(flag: bool, arg: &str) -> Box<Write> {
@@ -138,18 +159,37 @@ impl fmt::Display for ConfigurationError {
138159
}
139160
}
140161

162+
#[derive(Debug)]
163+
pub enum InputError {
164+
IOError((String, io::Error)),
165+
Mime(String),
166+
}
167+
168+
impl fmt::Display for InputError {
169+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
170+
match *self {
171+
InputError::IOError((ref file_path, ref io_err))
172+
=> writeln!(f, "Failed to open '{}' for reading with error: {}", file_path, io_err),
173+
InputError::Mime(ref mime)
174+
=> writeln!(f, "'{}' is not a known mime-type", mime),
175+
}
176+
}
177+
}
178+
141179
#[derive(Debug)]
142180
pub enum CLIError {
143181
Configuration(ConfigurationError),
144182
ParseError((&'static str, &'static str, String, String)),
145183
UnknownParameter(String),
146184
InvalidKeyValueSyntax(String),
185+
Input(InputError),
147186
}
148187

149188
impl fmt::Display for CLIError {
150189
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
151190
match *self {
152-
CLIError::Configuration(ref err) => writeln!(f, "Configuration -> {}", err),
191+
CLIError::Configuration(ref err) => write!(f, "Configuration -> {}", err),
192+
CLIError::Input(ref err) => write!(f, "Input -> {}", err),
153193
CLIError::ParseError((arg_name, type_name, ref value, ref err_desc))
154194
=> writeln!(f, "Failed to parse argument '{}' with value '{}' as {} with error: {}",
155195
arg_name, value, type_name, err_desc),

0 commit comments

Comments
 (0)