chore(code-up): latest version of all code

This commit is contained in:
Sebastian Thiel
2015-05-10 12:07:12 +02:00
parent 69b12104a9
commit 9e6c9537a5
676 changed files with 173597 additions and 77125 deletions

View File

@@ -4,6 +4,7 @@ use oauth2::{ApplicationSecret, ConsoleApplicationSecret, TokenStorage, Token};
use serde::json;
use mime::Mime;
use clap::{App, SubCommand};
use strsim;
use std::fs;
use std::env;
@@ -18,14 +19,54 @@ use std::default::Default;
const FIELD_SEP: char = '.';
// Based on @erickt user comment. Thanks for the idea !
// Remove all keys whose values are null from given value (changed in place)
pub fn remove_json_null_values(value: &mut json::value::Value) {
match *value {
json::value::Value::Object(ref mut map) => {
let mut for_removal = Vec::new();
for (key, mut value) in map.iter_mut() {
if value.is_null() {
for_removal.push(key.clone());
} else {
remove_json_null_values(&mut value);
}
}
for key in &for_removal {
map.remove(key);
}
}
_ => {}
}
}
fn did_you_mean<'a>(v: &str, possible_values: &[&'a str]) -> Option<&'a str> {
let mut candidate: Option<(f64, &str)> = None;
for pv in possible_values {
let confidence = strsim::jaro_winkler(v, pv);
if confidence > 0.8 && (candidate.is_none() || (candidate.as_ref().unwrap().0 < confidence)) {
candidate = Some((confidence, pv));
}
}
match candidate {
None => None,
Some((_, candidate)) => Some(candidate),
}
}
pub enum CallType {
Upload(UploadProtocol),
Standard,
}
pub enum UploadProtocol {
Simple,
Resumable,
arg_enum!{
pub enum UploadProtocol {
Simple,
Resumable
}
}
impl AsRef<str> for UploadProtocol {
@@ -46,18 +87,6 @@ impl AsRef<str> for CallType {
}
}
impl FromStr for UploadProtocol {
type Err = String;
fn from_str(s: &str) -> Result<UploadProtocol, String> {
match s {
"simple" => Ok(UploadProtocol::Simple),
"resumable" => Ok(UploadProtocol::Resumable),
_ => Err(format!("Protocol '{}' is unknown", s)),
}
}
}
#[derive(Clone, Default)]
pub struct FieldCursor(Vec<String>);
@@ -129,6 +158,49 @@ impl FieldCursor {
Ok(())
}
pub fn did_you_mean(value: &str, possible_values: &[&str]) -> Option<String> {
if value.len() == 0 {
return None
}
let mut last_c = FIELD_SEP;
let mut field = String::new();
let mut output = String::new();
let push_field = |fs: &mut String, f: &mut String| {
if f.len() > 0 {
fs.push_str(
match did_you_mean(&f, possible_values) {
Some(candidate) => candidate,
None => &f,
});
f.truncate(0);
}
};
for (cid, c) in value.chars().enumerate() {
if c == FIELD_SEP {
if last_c != FIELD_SEP {
push_field(&mut output, &mut field);
}
output.push(c);
} else {
field.push(c);
}
last_c = c;
}
push_field(&mut output, &mut field);
if &output == value {
None
} else {
Some(output)
}
}
pub fn num_fields(&self) -> usize {
self.0.len()
}
@@ -153,7 +225,7 @@ pub fn parse_kv_arg<'a>(kv: &'a str, err: &mut InvalidOptionsError, for_hashmap:
}
}
pub fn protocol_from_str(name: &str, valid_protocols: Vec<String>, err: &mut InvalidOptionsError) -> CallType {
pub fn calltype_from_str(name: &str, valid_protocols: Vec<String>, err: &mut InvalidOptionsError) -> CallType {
CallType::Upload(
match UploadProtocol::from_str(name) {
Ok(up) => up,
@@ -282,10 +354,10 @@ impl fmt::Display for ApplicationSecretError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
ApplicationSecretError::DecoderError((ref path, ref err))
=> writeln!(f, "Could not decode file at '{}' with error: {}",
=> writeln!(f, "Could not decode file at '{}' with error: {}.",
path, err),
ApplicationSecretError::FormatError(ref path)
=> writeln!(f, "'installed' field is unset in secret file at '{}'",
=> writeln!(f, "'installed' field is unset in secret file at '{}'.",
path),
}
}
@@ -304,15 +376,15 @@ impl fmt::Display for ConfigurationError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
ConfigurationError::DirectoryCreationFailed((ref dir, ref err))
=> writeln!(f, "Directory '{}' could not be created with error: {}", dir, err),
=> writeln!(f, "Directory '{}' could not be created with error: {}.", dir, err),
ConfigurationError::DirectoryUnset
=> writeln!(f, "--config-dir was unset or empty"),
=> writeln!(f, "--config-dir was unset or empty."),
ConfigurationError::HomeExpansionFailed(ref dir)
=> writeln!(f, "Couldn't find HOME directory of current user, failed to expand '{}'", dir),
=> writeln!(f, "Couldn't find HOME directory of current user, failed to expand '{}'.", dir),
ConfigurationError::Secret(ref err)
=> writeln!(f, "Secret -> {}", err),
ConfigurationError::IOError((ref path, ref err))
=> writeln!(f, "IO operation failed on path '{}' with error: {}", path, err),
=> writeln!(f, "IO operation failed on path '{}' with error: {}.", path, err),
}
}
}
@@ -327,9 +399,9 @@ 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),
=> 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),
=> writeln!(f, "'{}' is not a known mime-type.", mime),
}
}
}
@@ -338,7 +410,7 @@ impl fmt::Display for InputError {
pub enum FieldError {
PopOnEmpty(String),
TrailingFieldSep(String),
Unknown(String),
Unknown(String, Option<String>, Option<String>),
Empty,
}
@@ -347,13 +419,26 @@ impl fmt::Display for FieldError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
FieldError::PopOnEmpty(ref field)
=> writeln!(f, "'{}': Cannot move up on empty field cursor", field),
=> writeln!(f, "'{}': Cannot move up on empty field cursor.", field),
FieldError::TrailingFieldSep(ref field)
=> writeln!(f, "'{}': Single field separator may not be last character", field),
FieldError::Unknown(ref field)
=> writeln!(f, "Field '{}' does not exist", field),
=> writeln!(f, "'{}': Single field separator may not be last character.", field),
FieldError::Unknown(ref field, ref suggestion, ref value) => {
let suffix =
match *suggestion {
Some(ref s) => {
let kv =
match *value {
Some(ref v) => format!("{}={}", s, v),
None => s.clone(),
};
format!(" Did you mean '{}' ?", kv)
},
None => String::new(),
};
writeln!(f, "Field '{}' does not exist.{}", field, suffix)
},
FieldError::Empty
=> writeln!(f, "Field names must not be empty"),
=> writeln!(f, "Field names must not be empty."),
}
}
}
@@ -363,7 +448,7 @@ impl fmt::Display for FieldError {
pub enum CLIError {
Configuration(ConfigurationError),
ParseError(&'static str, &'static str, String, String),
UnknownParameter(String),
UnknownParameter(String, Vec<&'static str>),
InvalidUploadProtocol(String, Vec<String>),
InvalidKeyValueSyntax(String, bool),
Input(InputError),
@@ -379,18 +464,24 @@ impl fmt::Display for CLIError {
CLIError::Input(ref err) => write!(f, "Input -> {}", err),
CLIError::Field(ref err) => write!(f, "Field -> {}", err),
CLIError::InvalidUploadProtocol(ref proto_name, ref valid_names)
=> writeln!(f, "'{}' is not a valid upload protocol. Choose from one of {}", proto_name, valid_names.connect(", ")),
=> writeln!(f, "'{}' is not a valid upload protocol. Choose from one of {}.", proto_name, valid_names.connect(", ")),
CLIError::ParseError(arg_name, type_name, ref value, ref err_desc)
=> writeln!(f, "Failed to parse argument '{}' with value '{}' as {} with error: {}",
=> writeln!(f, "Failed to parse argument '{}' with value '{}' as {} with error: {}.",
arg_name, value, type_name, err_desc),
CLIError::UnknownParameter(ref param_name)
=> writeln!(f, "Parameter '{}' is unknown.", param_name),
CLIError::UnknownParameter(ref param_name, ref possible_values) => {
let mut suffix =
match did_you_mean(param_name, &possible_values) {
Some(v) => format!(" Did you mean '{}' ?", v),
None => String::new(),
};
write!(f, "Parameter '{}' is unknown.{}\n", param_name, suffix)
},
CLIError::InvalidKeyValueSyntax(ref kv, is_hashmap) => {
let hashmap_info = if is_hashmap { "hashmap " } else { "" };
writeln!(f, "'{}' does not match {}pattern <key>=<value>", kv, hashmap_info)
writeln!(f, "'{}' does not match {}pattern <key>=<value>.", kv, hashmap_info)
},
CLIError::MissingCommandError => writeln!(f, "Please specify the main sub-command"),
CLIError::MissingMethodError(ref cmd) => writeln!(f, "Please specify the method to call on the '{}' command", cmd),
CLIError::MissingCommandError => writeln!(f, "Please specify the main sub-command."),
CLIError::MissingMethodError(ref cmd) => writeln!(f, "Please specify the method to call on the '{}' command.", cmd),
}
}
}

View File

@@ -4,12 +4,14 @@
#![feature(plugin, exit_status)]
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
#[macro_use]
extern crate clap;
extern crate yup_oauth2 as oauth2;
extern crate yup_hyper_mock as mock;
extern crate serde;
extern crate hyper;
extern crate mime;
extern crate strsim;
extern crate google_groupsmigration1 as api;
use std::env;
@@ -20,7 +22,7 @@ mod cmn;
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError, CallType, UploadProtocol,
protocol_from_str};
calltype_from_str, remove_json_null_values};
use std::default::Default;
use std::str::FromStr;
@@ -37,6 +39,8 @@ enum DoitError {
struct Engine<'n, 'a> {
opt: ArgMatches<'n, 'a>,
hub: api::GroupsMigration<hyper::Client, Authenticator<DefaultAuthenticatorDelegate, JsonTokenStorage, hyper::Client>>,
gp: Vec<&'static str>,
gpm: Vec<(&'static str, &'static str)>,
}
@@ -47,26 +51,25 @@ impl<'n, 'a> Engine<'n, 'a> {
for parg in opt.values_of("v").unwrap_or(Vec::new()).iter() {
let (key, value) = parse_kv_arg(&*parg, err, false);
match key {
"alt"
|"fields"
|"key"
|"oauth-token"
|"pretty-print"
|"quota-user"
|"user-ip" => {
let map = [
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
];
call = call.param(map.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"))
},
_ => err.issues.push(CLIError::UnknownParameter(key.to_string())),
_ => {
let mut found = false;
for param in &self.gp {
if key == *param {
found = true;
call = call.param(self.gpm.iter().find(|t| t.0 == key).unwrap_or(&("", key)).1, value.unwrap_or("unset"));
break;
}
}
if !found {
err.issues.push(CLIError::UnknownParameter(key.to_string(),
Vec::new() + &self.gp + &[]
));
}
}
}
}
let vals = opt.values_of("mode").unwrap();
let protocol = protocol_from_str(vals[0], ["simple", "resumable"].iter().map(|&v| v.to_string()).collect(), err);
let protocol = calltype_from_str(vals[0], ["simple", "resumable"].iter().map(|&v| v.to_string()).collect(), err);
let mut input_file = input_file_from_opts(vals[1], err);
let mime_type = input_mime_from_opts(opt.value_of("mime").unwrap_or("application/octet-stream"), err);
if dry_run {
@@ -87,7 +90,9 @@ impl<'n, 'a> Engine<'n, 'a> {
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
Ok((mut response, output_schema)) => {
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
let mut value = json::value::to_value(&output_schema);
remove_json_null_values(&mut value);
serde::json::to_writer_pretty(&mut ostream, &value).unwrap();
Ok(())
}
}
@@ -165,6 +170,13 @@ impl<'n, 'a> Engine<'n, 'a> {
let engine = Engine {
opt: opt,
hub: api::GroupsMigration::new(client, auth),
gp: vec!["alt", "fields", "key", "oauth-token", "pretty-print", "quota-user", "user-ip"],
gpm: vec![
("oauth-token", "oauth_token"),
("pretty-print", "prettyPrint"),
("quota-user", "quotaUser"),
("user-ip", "userIp"),
]
};
match engine._doit(true) {
@@ -186,29 +198,31 @@ fn main() {
let upload_value_names = ["mode", "file"];
let arg_data = [
("archive", "methods: 'insert'", vec![
("insert", Some("Inserts a new mail into the archive of the Google group."),
("insert",
Some(r##"Inserts a new mail into the archive of the Google group."##),
"Details at http://byron.github.io/google-apis-rs/google_groupsmigration1_cli/archive_insert",
vec![
(Some("group-id"),
(Some(r##"group-id"##),
None,
Some("The group ID"),
Some(r##"The group ID"##),
Some(true),
Some(false)),
(Some("mode"),
Some("u"),
Some("Specify the upload protocol (simple|resumable) and the file to upload"),
(Some(r##"mode"##),
Some(r##"u"##),
Some(r##"Specify the upload protocol (simple|resumable) and the file to upload"##),
Some(true),
Some(true)),
(Some("v"),
Some("p"),
Some("Set various fields of the request structure"),
(Some(r##"v"##),
Some(r##"p"##),
Some(r##"Set various optional parameters, matching the key=value form"##),
Some(false),
Some(true)),
(Some("out"),
Some("o"),
Some("Specify the file into which to write the programs output"),
(Some(r##"out"##),
Some(r##"o"##),
Some(r##"Specify the file into which to write the program's output"##),
Some(false),
Some(false)),
]),
@@ -245,11 +259,12 @@ fn main() {
for &(main_command_name, ref about, ref subcommands) in arg_data.iter() {
let mut mcmd = SubCommand::new(main_command_name).about(about);
for &(sub_command_name, ref desc, ref args) in subcommands {
for &(sub_command_name, ref desc, url_info, ref args) in subcommands {
let mut scmd = SubCommand::new(sub_command_name);
if let &Some(desc) = desc {
scmd = scmd.about(desc);
}
scmd = scmd.after_help(url_info);
for &(ref arg_name, ref flag, ref desc, ref required, ref multi) in args {
let arg_name_str =