prepare release of version 2.0, regen all APIs

This commit is contained in:
Sebastian Thiel
2021-04-01 23:46:26 +08:00
parent f1c05f2554
commit c606d37dd3
3415 changed files with 3620084 additions and 2930380 deletions

View File

@@ -1,27 +1,26 @@
// COPY OF 'src/rust/cli/cmn.rs'
// COPY OF 'src/rust/cli/client.rs'
// DO NOT EDIT
use oauth2::{ApplicationSecret, ConsoleApplicationSecret, TokenStorage, Token};
use clap::{App, SubCommand};
use mime::Mime;
use oauth2::{ApplicationSecret, ConsoleApplicationSecret};
use serde_json as json;
use serde_json::value::Value;
use mime::Mime;
use clap::{App, SubCommand};
use strsim;
use std::fs;
use std::env;
use std::io;
use std::error::Error as StdError;
use std::fmt;
use std::fs;
use std::io;
use std::io::{stdout, Read, Write};
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::string::ToString;
use std::io::{Write, Read, stdout};
use std::default::Default;
const FIELD_SEP: char = '.';
pub enum ComplexType {
Pod,
Vec,
@@ -83,12 +82,11 @@ pub fn remove_json_null_values(value: &mut Value) {
}
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)) {
if confidence > 0.8 && (candidate.is_none() || (candidate.as_ref().unwrap().0 < confidence))
{
candidate = Some((confidence, pv));
}
}
@@ -103,10 +101,10 @@ pub enum CallType {
Standard,
}
arg_enum!{
arg_enum! {
pub enum UploadProtocol {
Simple,
Resumable
// Resumable // This seems to be lost during the async conversion
}
}
@@ -114,7 +112,7 @@ impl AsRef<str> for UploadProtocol {
fn as_ref(&self) -> &str {
match *self {
UploadProtocol::Simple => "simple",
UploadProtocol::Resumable => "resumable",
// UploadProtocol::Resumable => "resumable",
}
}
}
@@ -131,7 +129,7 @@ impl AsRef<str> for CallType {
#[derive(Clone, Default)]
pub struct FieldCursor(Vec<String>);
impl ToString for FieldCursor {
impl ToString for FieldCursor {
fn to_string(&self) -> String {
self.0.join(".")
}
@@ -208,7 +206,9 @@ impl FieldCursor {
fields.truncate(0);
}
if char_count > 1 && num_conscutive_field_seps == 1 {
return Err(CLIError::Field(FieldError::TrailingFieldSep(value.to_string())));
return Err(CLIError::Field(FieldError::TrailingFieldSep(
value.to_string(),
)));
}
self.0 = fields;
@@ -257,20 +257,20 @@ impl FieldCursor {
}
}
pub fn set_json_value(&self,
mut object: &mut Value,
value: &str,
type_info: JsonTypeInfo,
err: &mut InvalidOptionsError,
orig_cursor: &FieldCursor) {
pub fn set_json_value(
&self,
mut object: &mut Value,
value: &str,
type_info: JsonTypeInfo,
err: &mut InvalidOptionsError,
orig_cursor: &FieldCursor,
) {
assert!(self.0.len() > 0);
for field in &self.0[..self.0.len() - 1] {
let tmp = object;
object = match *tmp {
Value::Object(ref mut mapping) => {
assure_entry(mapping, &field)
}
Value::Object(ref mut mapping) => assure_entry(mapping, &field),
_ => panic!("We don't expect non-object Values here ..."),
};
}
@@ -278,58 +278,55 @@ impl FieldCursor {
match *object {
Value::Object(ref mut mapping) => {
let field = &self.0[self.0.len() - 1];
let to_jval = |value: &str,
jtype: JsonType,
err: &mut InvalidOptionsError|
-> Value {
match jtype {
JsonType::Boolean =>
Value::Bool(arg_from_str(value, err, &field, "boolean")),
JsonType::Int =>
Value::Number(json::Number::from_f64(arg_from_str(value,
err,
&field,
"int"))
.expect("valid f64")),
JsonType::Uint =>
Value::Number(json::Number::from_f64(arg_from_str(value,
err,
&field,
"uint"))
.expect("valid f64")),
JsonType::Float =>
Value::Number(json::Number::from_f64(arg_from_str(value,
err,
&field,
"float"))
.expect("valid f64")),
JsonType::String => Value::String(value.to_owned()),
}
};
let to_jval =
|value: &str, jtype: JsonType, err: &mut InvalidOptionsError| -> Value {
match jtype {
JsonType::Boolean => {
Value::Bool(arg_from_str(value, err, &field, "boolean"))
}
JsonType::Int => Value::Number(
json::Number::from_f64(arg_from_str(value, err, &field, "int"))
.expect("valid f64"),
),
JsonType::Uint => Value::Number(
json::Number::from_f64(arg_from_str(value, err, &field, "uint"))
.expect("valid f64"),
),
JsonType::Float => Value::Number(
json::Number::from_f64(arg_from_str(value, err, &field, "float"))
.expect("valid f64"),
),
JsonType::String => Value::String(value.to_owned()),
}
};
match type_info.ctype {
ComplexType::Pod => {
if mapping.insert(field.to_owned(), to_jval(value, type_info.jtype, err))
.is_some() {
err.issues.push(CLIError::Field(FieldError::Duplicate(orig_cursor.to_string())));
if mapping
.insert(field.to_owned(), to_jval(value, type_info.jtype, err))
.is_some()
{
err.issues.push(CLIError::Field(FieldError::Duplicate(
orig_cursor.to_string(),
)));
}
}
ComplexType::Vec => {
match *assure_entry(mapping, field) {
Value::Array(ref mut values) =>
values.push(to_jval(value, type_info.jtype, err)),
_ => unreachable!(),
ComplexType::Vec => match *assure_entry(mapping, field) {
Value::Array(ref mut values) => {
values.push(to_jval(value, type_info.jtype, err))
}
}
_ => unreachable!(),
},
ComplexType::Map => {
let (key, value) = parse_kv_arg(value, err, true);
let jval = to_jval(value.unwrap_or(""), type_info.jtype, err);
match *assure_entry(mapping, &field) {
Value::Object(ref mut value_map) => {
if value_map.insert(key.to_owned(), jval).is_some() {
err.issues.push(CLIError::Field(FieldError::Duplicate(orig_cursor.to_string())));
err.issues.push(CLIError::Field(FieldError::Duplicate(
orig_cursor.to_string(),
)));
}
}
_ => unreachable!(),
@@ -346,12 +343,14 @@ impl FieldCursor {
}
}
pub fn parse_kv_arg<'a>(kv: &'a str,
err: &mut InvalidOptionsError,
for_hashmap: bool)
-> (&'a str, Option<&'a str>) {
pub fn parse_kv_arg<'a>(
kv: &'a str,
err: &mut InvalidOptionsError,
for_hashmap: bool,
) -> (&'a str, Option<&'a str>) {
let mut add_err = || {
err.issues.push(CLIError::InvalidKeyValueSyntax(kv.to_string(), for_hashmap))
err.issues
.push(CLIError::InvalidKeyValueSyntax(kv.to_string(), for_hashmap))
};
match kv.find('=') {
None => {
@@ -369,14 +368,18 @@ pub fn parse_kv_arg<'a>(kv: &'a str,
}
}
pub fn calltype_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,
Err(msg) => {
err.issues.push(CLIError::InvalidUploadProtocol(name.to_string(), valid_protocols));
err.issues.push(CLIError::InvalidUploadProtocol(
name.to_string(),
valid_protocols,
));
UploadProtocol::Simple
}
})
@@ -386,7 +389,10 @@ pub fn input_file_from_opts(file_path: &str, err: &mut InvalidOptionsError) -> O
match fs::File::open(file_path) {
Ok(f) => Some(f),
Err(io_err) => {
err.issues.push(CLIError::Input(InputError::Io((file_path.to_string(), io_err))));
err.issues.push(CLIError::Input(InputError::Io((
file_path.to_string(),
io_err,
))));
None
}
}
@@ -396,7 +402,8 @@ pub fn input_mime_from_opts(mime: &str, err: &mut InvalidOptionsError) -> Option
match mime.parse() {
Ok(m) => Some(m),
Err(_) => {
err.issues.push(CLIError::Input(InputError::Mime(mime.to_string())));
err.issues
.push(CLIError::Input(InputError::Mime(mime.to_string())));
None
}
}
@@ -406,120 +413,42 @@ pub fn writer_from_opts(arg: Option<&str>) -> Result<Box<dyn Write>, io::Error>
let f = arg.unwrap_or("-");
match f {
"-" => Ok(Box::new(stdout())),
_ => match fs::OpenOptions::new().create(true).truncate(true).write(true).open(f) {
_ => match fs::OpenOptions::new()
.create(true)
.truncate(true)
.write(true)
.open(f)
{
Ok(f) => Ok(Box::new(f)),
Err(io_err) => Err(io_err),
},
}
}
pub fn arg_from_str<'a, T>(arg: &str,
err: &mut InvalidOptionsError,
arg_name: &'a str,
arg_type: &'a str)
-> T
where T: FromStr + Default,
<T as FromStr>::Err: fmt::Display
pub fn arg_from_str<'a, T>(
arg: &str,
err: &mut InvalidOptionsError,
arg_name: &'a str,
arg_type: &'a str,
) -> T
where
T: FromStr + Default,
<T as FromStr>::Err: fmt::Display,
{
match FromStr::from_str(arg) {
Err(perr) => {
err.issues.push(CLIError::ParseError(arg_name.to_owned(),
arg_type.to_owned(),
arg.to_string(),
format!("{}", perr)));
err.issues.push(CLIError::ParseError(
arg_name.to_owned(),
arg_type.to_owned(),
arg.to_string(),
format!("{}", perr),
));
Default::default()
}
Ok(v) => v,
}
}
pub struct JsonTokenStorage {
pub program_name: &'static str,
pub db_dir: String,
}
impl JsonTokenStorage {
fn path(&self, scope_hash: u64) -> PathBuf {
Path::new(&self.db_dir).join(&format!("{}-token-{}.json", self.program_name, scope_hash))
}
}
#[derive(Debug)]
pub enum TokenStorageError {
Json(json::Error),
Io(io::Error),
}
impl fmt::Display for TokenStorageError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
TokenStorageError::Json(ref err) => writeln!(f, "Could not serialize secrets: {}", err),
TokenStorageError::Io(ref err) => writeln!(f, "Failed to write secret token: {}", err),
}
}
}
impl StdError for TokenStorageError {
fn description(&self) -> &str {
"Failure when getting or setting the token storage"
}
}
impl TokenStorage for JsonTokenStorage {
type Error = TokenStorageError;
// NOTE: logging might be interesting, currently we swallow all errors
fn set(&mut self,
scope_hash: u64,
_: &Vec<&str>,
token: Option<Token>)
-> Result<(), TokenStorageError> {
match token {
None => {
match fs::remove_file(self.path(scope_hash)) {
Err(err) => match err.kind() {
io::ErrorKind::NotFound => Ok(()),
_ => Err(TokenStorageError::Io(err)),
},
Ok(_) => Ok(()),
}
}
Some(token) => {
match fs::OpenOptions::new().create(true).write(true).truncate(true).open(&self.path(scope_hash)) {
Ok(mut f) => {
match json::to_writer_pretty(&mut f, &token) {
Ok(_) => Ok(()),
Err(serde_err) => Err(TokenStorageError::Json(serde_err)),
}
}
Err(io_err) => Err(TokenStorageError::Io(io_err)),
}
}
}
}
fn get(&self, scope_hash: u64, _: &Vec<&str>) -> Result<Option<Token>, TokenStorageError> {
match fs::File::open(&self.path(scope_hash)) {
Ok(f) => {
match json::de::from_reader(f) {
Ok(token) => Ok(Some(token)),
Err(err) => Err(TokenStorageError::Json(err)),
}
}
Err(io_err) => {
match io_err.kind() {
io::ErrorKind::NotFound => Ok(None),
_ => Err(TokenStorageError::Io(io_err)),
}
}
}
}
}
#[derive(Debug)]
pub enum ApplicationSecretError {
DecoderError((String, json::Error)),
@@ -529,15 +458,16 @@ pub enum ApplicationSecretError {
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: {}.",
path,
err),
ApplicationSecretError::FormatError(ref path) =>
writeln!(f,
"'installed' field is unset in secret file at '{}'.",
path),
ApplicationSecretError::DecoderError((ref path, ref err)) => 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 '{}'.",
path
),
}
}
}
@@ -554,22 +484,23 @@ pub enum ConfigurationError {
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),
ConfigurationError::DirectoryCreationFailed((ref dir, ref err)) => writeln!(
f,
"Directory '{}' could not be created with error: {}.",
dir, err
),
ConfigurationError::DirectoryUnset => 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),
ConfigurationError::HomeExpansionFailed(ref dir) => writeln!(
f,
"Couldn't find HOME directory of current user, failed to expand '{}'.",
dir
),
ConfigurationError::Secret(ref err) => writeln!(f, "Secret -> {}", err),
ConfigurationError::Io((ref path, ref err)) =>
writeln!(f,
"IO operation failed on path '{}' with error: {}.",
path,
err),
ConfigurationError::Io((ref path, ref err)) => writeln!(
f,
"IO operation failed on path '{}' with error: {}.",
path, err
),
}
}
}
@@ -583,11 +514,11 @@ pub enum InputError {
impl fmt::Display for InputError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
InputError::Io((ref file_path, ref io_err)) =>
writeln!(f,
"Failed to open '{}' for reading with error: {}.",
file_path,
io_err),
InputError::Io((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),
}
}
@@ -602,16 +533,17 @@ pub enum FieldError {
Empty,
}
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),
FieldError::TrailingFieldSep(ref field) =>
writeln!(f,
"'{}': Single field separator may not be last character.",
field),
FieldError::PopOnEmpty(ref 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, ref suggestion, ref value) => {
let suffix = match *suggestion {
Some(ref s) => {
@@ -625,14 +557,14 @@ impl fmt::Display for FieldError {
};
writeln!(f, "Field '{}' does not exist.{}", field, suffix)
}
FieldError::Duplicate(ref cursor) =>
writeln!(f, "Value at '{}' was already set", cursor),
FieldError::Duplicate(ref cursor) => {
writeln!(f, "Value at '{}' was already set", cursor)
}
FieldError::Empty => writeln!(f, "Field names must not be empty."),
}
}
}
#[derive(Debug)]
pub enum CLIError {
Configuration(ConfigurationError),
@@ -652,18 +584,17 @@ impl fmt::Display for CLIError {
CLIError::Configuration(ref err) => write!(f, "Configuration -> {}", err),
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.join(", ")),
CLIError::ParseError(ref arg_name, ref 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),
CLIError::InvalidUploadProtocol(ref proto_name, ref valid_names) => writeln!(
f,
"'{}' is not a valid upload protocol. Choose from one of {}.",
proto_name,
valid_names.join(", ")
),
CLIError::ParseError(ref arg_name, ref 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
),
CLIError::UnknownParameter(ref param_name, ref possible_values) => {
let suffix = match did_you_mean(param_name, &possible_values) {
Some(v) => format!(" Did you mean '{}' ?", v),
@@ -672,21 +603,19 @@ impl fmt::Display for CLIError {
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)
let hashmap_info = if is_hashmap { "hashmap " } else { "" };
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::MissingMethodError(ref cmd) => writeln!(
f,
"Please specify the method to call on the '{}' command.",
cmd
),
}
}
}
@@ -730,7 +659,11 @@ pub fn assure_config_dir_exists(dir: &str) -> Result<String, CLIError> {
let expanded_config_dir = if trdir.as_bytes()[0] == b'~' {
match env::var("HOME").ok().or(env::var("UserProfile").ok()) {
None => return Err(CLIError::Configuration(ConfigurationError::HomeExpansionFailed(trdir.to_string()))),
None => {
return Err(CLIError::Configuration(
ConfigurationError::HomeExpansionFailed(trdir.to_string()),
))
}
Some(mut user) => {
user.push_str(&trdir[1..]);
user
@@ -743,21 +676,26 @@ pub fn assure_config_dir_exists(dir: &str) -> Result<String, CLIError> {
if let Err(err) = fs::create_dir(&expanded_config_dir) {
if err.kind() != io::ErrorKind::AlreadyExists {
return Err(CLIError::Configuration(
ConfigurationError::DirectoryCreationFailed((expanded_config_dir, err))));
ConfigurationError::DirectoryCreationFailed((expanded_config_dir, err)),
));
}
}
Ok(expanded_config_dir)
}
pub fn application_secret_from_directory(dir: &str,
secret_basename: &str,
json_console_secret: &str)
-> Result<ApplicationSecret, CLIError> {
pub fn application_secret_from_directory(
dir: &str,
secret_basename: &str,
json_console_secret: &str,
) -> Result<ApplicationSecret, CLIError> {
let secret_path = Path::new(dir).join(secret_basename);
let secret_str = || secret_path.as_path().to_str().unwrap().to_string();
let secret_io_error = |io_err: io::Error| {
Err(CLIError::Configuration(ConfigurationError::Io((secret_str(), io_err))))
Err(CLIError::Configuration(ConfigurationError::Io((
secret_str(),
io_err,
))))
};
for _ in 0..2 {
@@ -767,18 +705,20 @@ pub fn application_secret_from_directory(dir: &str,
// Write our built-in one - user may adjust the written file at will
err = match fs::OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&secret_path) {
.create(true)
.write(true)
.truncate(true)
.open(&secret_path)
{
Err(cfe) => cfe,
Ok(mut f) => {
// Assure we convert 'ugly' json string into pretty one
let console_secret: ConsoleApplicationSecret =
json::from_str(json_console_secret).unwrap();
match json::to_writer_pretty(&mut f, &console_secret) {
Err(serde_err) =>
panic!("Unexpected serde error: {:#?}", serde_err),
Err(serde_err) => {
panic!("Unexpected serde error: {:#?}", serde_err)
}
Ok(_) => continue,
}
}
@@ -787,24 +727,21 @@ pub fn application_secret_from_directory(dir: &str,
}
return secret_io_error(err);
}
Ok(f) => {
match json::de::from_reader::<_, ConsoleApplicationSecret>(f) {
Err(json_err) =>
return Err(CLIError::Configuration(
ConfigurationError::Secret(
ApplicationSecretError::DecoderError(
(secret_str(), json_err)
)))),
Ok(console_secret) => match console_secret.installed {
Some(secret) => return Ok(secret),
None => return Err(
CLIError::Configuration(
ConfigurationError::Secret(
ApplicationSecretError::FormatError(secret_str())
))),
},
Ok(f) => match json::de::from_reader::<_, ConsoleApplicationSecret>(f) {
Err(json_err) => {
return Err(CLIError::Configuration(ConfigurationError::Secret(
ApplicationSecretError::DecoderError((secret_str(), json_err)),
)))
}
}
Ok(console_secret) => match console_secret.installed {
Some(secret) => return Ok(secret),
None => {
return Err(CLIError::Configuration(ConfigurationError::Secret(
ApplicationSecretError::FormatError(secret_str()),
)))
}
},
},
}
}
unreachable!();

View File

@@ -3,50 +3,46 @@
// DO NOT EDIT !
#![allow(unused_variables, unused_imports, dead_code, unused_mut)]
extern crate tokio;
#[macro_use]
extern crate clap;
extern crate yup_oauth2 as oauth2;
extern crate yup_hyper_mock as mock;
extern crate hyper_rustls;
extern crate serde;
extern crate serde_json;
extern crate hyper;
extern crate mime;
extern crate strsim;
extern crate google_billingbudgets1_beta1 as api;
use std::env;
use std::io::{self, Write};
use clap::{App, SubCommand, Arg};
mod cmn;
use google_billingbudgets1_beta1::{api, Error};
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
mod client;
use client::{InvalidOptionsError, CLIError, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError, CallType, UploadProtocol,
calltype_from_str, remove_json_null_values, ComplexType, JsonType, JsonTypeInfo};
use std::default::Default;
use std::str::FromStr;
use oauth2::{Authenticator, DefaultAuthenticatorDelegate, FlowType};
use serde_json as json;
use clap::ArgMatches;
enum DoitError {
IoError(String, io::Error),
ApiError(api::Error),
ApiError(Error),
}
struct Engine<'n> {
opt: ArgMatches<'n>,
hub: api::CloudBillingBudget<hyper::Client, Authenticator<DefaultAuthenticatorDelegate, JsonTokenStorage, hyper::Client>>,
hub: api::CloudBillingBudget<hyper::Client<hyper_rustls::HttpsConnector<hyper::client::connect::HttpConnector>, hyper::body::Body>
>,
gp: Vec<&'static str>,
gpm: Vec<(&'static str, &'static str)>,
}
impl<'n> Engine<'n> {
fn _billing_accounts_budgets_create(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
async fn _billing_accounts_budgets_create(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
-> Result<(), DoitError> {
let mut field_cursor = FieldCursor::default();
@@ -69,20 +65,30 @@ impl<'n> Engine<'n> {
let type_info: Option<(&'static str, JsonTypeInfo)> =
match &temp_cursor.to_string()[..] {
"budget.all-updates-rule.disable-default-iam-recipients" => Some(("budget.allUpdatesRule.disableDefaultIamRecipients", JsonTypeInfo { jtype: JsonType::Boolean, ctype: ComplexType::Pod })),
"budget.all-updates-rule.monitoring-notification-channels" => Some(("budget.allUpdatesRule.monitoringNotificationChannels", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.all-updates-rule.pubsub-topic" => Some(("budget.allUpdatesRule.pubsubTopic", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.all-updates-rule.schema-version" => Some(("budget.allUpdatesRule.schemaVersion", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.display-name" => Some(("budget.displayName", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.name" => Some(("budget.name", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.services" => Some(("budget.budgetFilter.services", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.credit-types-treatment" => Some(("budget.budgetFilter.creditTypesTreatment", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.subaccounts" => Some(("budget.budgetFilter.subaccounts", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.projects" => Some(("budget.budgetFilter.projects", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.amount.specified-amount.currency-code" => Some(("budget.amount.specifiedAmount.currencyCode", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.nanos" => Some(("budget.amount.specifiedAmount.nanos", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.units" => Some(("budget.amount.specifiedAmount.units", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.currency-code" => Some(("budget.amount.specifiedAmount.currencyCode", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.calendar-period" => Some(("budget.budgetFilter.calendarPeriod", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.credit-types" => Some(("budget.budgetFilter.creditTypes", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.credit-types-treatment" => Some(("budget.budgetFilter.creditTypesTreatment", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.day" => Some(("budget.budgetFilter.customPeriod.endDate.day", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.month" => Some(("budget.budgetFilter.customPeriod.endDate.month", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.year" => Some(("budget.budgetFilter.customPeriod.endDate.year", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.day" => Some(("budget.budgetFilter.customPeriod.startDate.day", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.month" => Some(("budget.budgetFilter.customPeriod.startDate.month", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.year" => Some(("budget.budgetFilter.customPeriod.startDate.year", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.projects" => Some(("budget.budgetFilter.projects", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.services" => Some(("budget.budgetFilter.services", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.subaccounts" => Some(("budget.budgetFilter.subaccounts", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.display-name" => Some(("budget.displayName", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.etag" => Some(("budget.etag", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.name" => Some(("budget.name", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
_ => {
let suggestion = FieldCursor::did_you_mean(key, &vec!["all-updates-rule", "amount", "budget", "budget-filter", "credit-types-treatment", "currency-code", "display-name", "etag", "name", "nanos", "projects", "pubsub-topic", "schema-version", "services", "specified-amount", "subaccounts", "units"]);
let suggestion = FieldCursor::did_you_mean(key, &vec!["all-updates-rule", "amount", "budget", "budget-filter", "calendar-period", "credit-types", "credit-types-treatment", "currency-code", "custom-period", "day", "disable-default-iam-recipients", "display-name", "end-date", "etag", "monitoring-notification-channels", "month", "name", "nanos", "projects", "pubsub-topic", "schema-version", "services", "specified-amount", "start-date", "subaccounts", "units", "year"]);
err.issues.push(CLIError::Field(FieldError::Unknown(temp_cursor.to_string(), suggestion, value.map(|v| v.to_string()))));
None
}
@@ -127,7 +133,7 @@ impl<'n> Engine<'n> {
Err(io_err) => return Err(DoitError::IoError(opt.value_of("out").unwrap_or("-").to_string(), io_err)),
};
match match protocol {
CallType::Standard => call.doit(),
CallType::Standard => call.doit().await,
_ => unreachable!()
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
@@ -142,7 +148,7 @@ impl<'n> Engine<'n> {
}
}
fn _billing_accounts_budgets_delete(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
async fn _billing_accounts_budgets_delete(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
-> Result<(), DoitError> {
let mut call = self.hub.billing_accounts().budgets_delete(opt.value_of("name").unwrap_or(""));
for parg in opt.values_of("v").map(|i|i.collect()).unwrap_or(Vec::new()).iter() {
@@ -179,7 +185,7 @@ impl<'n> Engine<'n> {
Err(io_err) => return Err(DoitError::IoError(opt.value_of("out").unwrap_or("-").to_string(), io_err)),
};
match match protocol {
CallType::Standard => call.doit(),
CallType::Standard => call.doit().await,
_ => unreachable!()
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
@@ -194,7 +200,7 @@ impl<'n> Engine<'n> {
}
}
fn _billing_accounts_budgets_get(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
async fn _billing_accounts_budgets_get(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
-> Result<(), DoitError> {
let mut call = self.hub.billing_accounts().budgets_get(opt.value_of("name").unwrap_or(""));
for parg in opt.values_of("v").map(|i|i.collect()).unwrap_or(Vec::new()).iter() {
@@ -231,7 +237,7 @@ impl<'n> Engine<'n> {
Err(io_err) => return Err(DoitError::IoError(opt.value_of("out").unwrap_or("-").to_string(), io_err)),
};
match match protocol {
CallType::Standard => call.doit(),
CallType::Standard => call.doit().await,
_ => unreachable!()
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
@@ -246,7 +252,7 @@ impl<'n> Engine<'n> {
}
}
fn _billing_accounts_budgets_list(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
async fn _billing_accounts_budgets_list(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
-> Result<(), DoitError> {
let mut call = self.hub.billing_accounts().budgets_list(opt.value_of("parent").unwrap_or(""));
for parg in opt.values_of("v").map(|i|i.collect()).unwrap_or(Vec::new()).iter() {
@@ -290,7 +296,7 @@ impl<'n> Engine<'n> {
Err(io_err) => return Err(DoitError::IoError(opt.value_of("out").unwrap_or("-").to_string(), io_err)),
};
match match protocol {
CallType::Standard => call.doit(),
CallType::Standard => call.doit().await,
_ => unreachable!()
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
@@ -305,7 +311,7 @@ impl<'n> Engine<'n> {
}
}
fn _billing_accounts_budgets_patch(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
async fn _billing_accounts_budgets_patch(&self, opt: &ArgMatches<'n>, dry_run: bool, err: &mut InvalidOptionsError)
-> Result<(), DoitError> {
let mut field_cursor = FieldCursor::default();
@@ -328,21 +334,31 @@ impl<'n> Engine<'n> {
let type_info: Option<(&'static str, JsonTypeInfo)> =
match &temp_cursor.to_string()[..] {
"budget.all-updates-rule.disable-default-iam-recipients" => Some(("budget.allUpdatesRule.disableDefaultIamRecipients", JsonTypeInfo { jtype: JsonType::Boolean, ctype: ComplexType::Pod })),
"budget.all-updates-rule.monitoring-notification-channels" => Some(("budget.allUpdatesRule.monitoringNotificationChannels", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.all-updates-rule.pubsub-topic" => Some(("budget.allUpdatesRule.pubsubTopic", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.all-updates-rule.schema-version" => Some(("budget.allUpdatesRule.schemaVersion", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.display-name" => Some(("budget.displayName", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.name" => Some(("budget.name", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.services" => Some(("budget.budgetFilter.services", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.credit-types-treatment" => Some(("budget.budgetFilter.creditTypesTreatment", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.subaccounts" => Some(("budget.budgetFilter.subaccounts", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.projects" => Some(("budget.budgetFilter.projects", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.amount.specified-amount.currency-code" => Some(("budget.amount.specifiedAmount.currencyCode", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.nanos" => Some(("budget.amount.specifiedAmount.nanos", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.units" => Some(("budget.amount.specifiedAmount.units", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.amount.specified-amount.currency-code" => Some(("budget.amount.specifiedAmount.currencyCode", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.calendar-period" => Some(("budget.budgetFilter.calendarPeriod", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.credit-types" => Some(("budget.budgetFilter.creditTypes", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.credit-types-treatment" => Some(("budget.budgetFilter.creditTypesTreatment", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.day" => Some(("budget.budgetFilter.customPeriod.endDate.day", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.month" => Some(("budget.budgetFilter.customPeriod.endDate.month", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.end-date.year" => Some(("budget.budgetFilter.customPeriod.endDate.year", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.day" => Some(("budget.budgetFilter.customPeriod.startDate.day", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.month" => Some(("budget.budgetFilter.customPeriod.startDate.month", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.custom-period.start-date.year" => Some(("budget.budgetFilter.customPeriod.startDate.year", JsonTypeInfo { jtype: JsonType::Int, ctype: ComplexType::Pod })),
"budget.budget-filter.projects" => Some(("budget.budgetFilter.projects", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.services" => Some(("budget.budgetFilter.services", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.budget-filter.subaccounts" => Some(("budget.budgetFilter.subaccounts", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Vec })),
"budget.display-name" => Some(("budget.displayName", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.etag" => Some(("budget.etag", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"budget.name" => Some(("budget.name", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
"update-mask" => Some(("updateMask", JsonTypeInfo { jtype: JsonType::String, ctype: ComplexType::Pod })),
_ => {
let suggestion = FieldCursor::did_you_mean(key, &vec!["all-updates-rule", "amount", "budget", "budget-filter", "credit-types-treatment", "currency-code", "display-name", "etag", "name", "nanos", "projects", "pubsub-topic", "schema-version", "services", "specified-amount", "subaccounts", "units", "update-mask"]);
let suggestion = FieldCursor::did_you_mean(key, &vec!["all-updates-rule", "amount", "budget", "budget-filter", "calendar-period", "credit-types", "credit-types-treatment", "currency-code", "custom-period", "day", "disable-default-iam-recipients", "display-name", "end-date", "etag", "monitoring-notification-channels", "month", "name", "nanos", "projects", "pubsub-topic", "schema-version", "services", "specified-amount", "start-date", "subaccounts", "units", "update-mask", "year"]);
err.issues.push(CLIError::Field(FieldError::Unknown(temp_cursor.to_string(), suggestion, value.map(|v| v.to_string()))));
None
}
@@ -387,7 +403,7 @@ impl<'n> Engine<'n> {
Err(io_err) => return Err(DoitError::IoError(opt.value_of("out").unwrap_or("-").to_string(), io_err)),
};
match match protocol {
CallType::Standard => call.doit(),
CallType::Standard => call.doit().await,
_ => unreachable!()
} {
Err(api_err) => Err(DoitError::ApiError(api_err)),
@@ -402,7 +418,7 @@ impl<'n> Engine<'n> {
}
}
fn _doit(&self, dry_run: bool) -> Result<Result<(), DoitError>, Option<InvalidOptionsError>> {
async fn _doit(&self, dry_run: bool) -> Result<Result<(), DoitError>, Option<InvalidOptionsError>> {
let mut err = InvalidOptionsError::new();
let mut call_result: Result<(), DoitError> = Ok(());
let mut err_opt: Option<InvalidOptionsError> = None;
@@ -410,19 +426,19 @@ impl<'n> Engine<'n> {
("billing-accounts", Some(opt)) => {
match opt.subcommand() {
("budgets-create", Some(opt)) => {
call_result = self._billing_accounts_budgets_create(opt, dry_run, &mut err);
call_result = self._billing_accounts_budgets_create(opt, dry_run, &mut err).await;
},
("budgets-delete", Some(opt)) => {
call_result = self._billing_accounts_budgets_delete(opt, dry_run, &mut err);
call_result = self._billing_accounts_budgets_delete(opt, dry_run, &mut err).await;
},
("budgets-get", Some(opt)) => {
call_result = self._billing_accounts_budgets_get(opt, dry_run, &mut err);
call_result = self._billing_accounts_budgets_get(opt, dry_run, &mut err).await;
},
("budgets-list", Some(opt)) => {
call_result = self._billing_accounts_budgets_list(opt, dry_run, &mut err);
call_result = self._billing_accounts_budgets_list(opt, dry_run, &mut err).await;
},
("budgets-patch", Some(opt)) => {
call_result = self._billing_accounts_budgets_patch(opt, dry_run, &mut err);
call_result = self._billing_accounts_budgets_patch(opt, dry_run, &mut err).await;
},
_ => {
err.issues.push(CLIError::MissingMethodError("billing-accounts".to_string()));
@@ -447,41 +463,26 @@ impl<'n> Engine<'n> {
}
// Please note that this call will fail if any part of the opt can't be handled
fn new(opt: ArgMatches<'n>) -> Result<Engine<'n>, InvalidOptionsError> {
async fn new(opt: ArgMatches<'n>) -> Result<Engine<'n>, InvalidOptionsError> {
let (config_dir, secret) = {
let config_dir = match cmn::assure_config_dir_exists(opt.value_of("folder").unwrap_or("~/.google-service-cli")) {
let config_dir = match client::assure_config_dir_exists(opt.value_of("folder").unwrap_or("~/.google-service-cli")) {
Err(e) => return Err(InvalidOptionsError::single(e, 3)),
Ok(p) => p,
};
match cmn::application_secret_from_directory(&config_dir, "billingbudgets1-beta1-secret.json",
match client::application_secret_from_directory(&config_dir, "billingbudgets1-beta1-secret.json",
"{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"client_secret\":\"hCsslbCUyfehWMmbkG8vTYxG\",\"token_uri\":\"https://accounts.google.com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\"620010449518-9ngf7o4dhs0dka470npqvor6dc5lqb9b.apps.googleusercontent.com\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}") {
Ok(secret) => (config_dir, secret),
Err(e) => return Err(InvalidOptionsError::single(e, 4))
}
};
let auth = Authenticator::new( &secret, DefaultAuthenticatorDelegate,
if opt.is_present("debug-auth") {
hyper::Client::with_connector(mock::TeeConnector {
connector: hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new())
})
} else {
hyper::Client::with_connector(hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new()))
},
JsonTokenStorage {
program_name: "billingbudgets1-beta1",
db_dir: config_dir.clone(),
}, Some(FlowType::InstalledRedirect(54324)));
let auth = yup_oauth2::InstalledFlowAuthenticator::builder(
secret,
yup_oauth2::InstalledFlowReturnMethod::HTTPRedirect,
).persist_tokens_to_disk(format!("{}/billingbudgets1-beta1", config_dir)).build().await.unwrap();
let client =
if opt.is_present("debug") {
hyper::Client::with_connector(mock::TeeConnector {
connector: hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new())
})
} else {
hyper::Client::with_connector(hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new()))
};
let client = hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots());
let engine = Engine {
opt: opt,
hub: api::CloudBillingBudget::new(client, auth),
@@ -497,35 +498,33 @@ impl<'n> Engine<'n> {
]
};
match engine._doit(true) {
match engine._doit(true).await {
Err(Some(err)) => Err(err),
Err(None) => Ok(engine),
Ok(_) => unreachable!(),
}
}
fn doit(&self) -> Result<(), DoitError> {
match self._doit(false) {
async fn doit(&self) -> Result<(), DoitError> {
match self._doit(false).await {
Ok(res) => res,
Err(_) => unreachable!(),
}
}
}
fn main() {
#[tokio::main]
async fn main() {
let mut exit_status = 0i32;
let arg_data = [
("billing-accounts", "methods: 'budgets-create', 'budgets-delete', 'budgets-get', 'budgets-list' and 'budgets-patch'", vec![
("budgets-create",
Some(r##"Creates a new budget. See
<a href="https://cloud.google.com/billing/quotas">Quotas and limits</a>
for more information on the limits of the number of budgets you can create."##),
Some(r##"Creates a new budget. See Quotas and limits for more information on the limits of the number of budgets you can create."##),
"Details at http://byron.github.io/google-apis-rs/google_billingbudgets1_beta1_cli/billing-accounts_budgets-create",
vec![
(Some(r##"parent"##),
None,
Some(r##"Required. The name of the billing account to create the budget in. Values
are of the form `billingAccounts/{billingAccountId}`."##),
Some(r##"Required. The name of the billing account to create the budget in. Values are of the form `billingAccounts/{billingAccountId}`."##),
Some(true),
Some(false)),
@@ -553,8 +552,7 @@ fn main() {
vec![
(Some(r##"name"##),
None,
Some(r##"Required. Name of the budget to delete. Values are of the form
`billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(r##"Required. Name of the budget to delete. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(true),
Some(false)),
@@ -571,18 +569,12 @@ fn main() {
Some(false)),
]),
("budgets-get",
Some(r##"Returns a budget.
WARNING: There are some fields exposed on the Google Cloud Console that
aren't available on this API. When reading from the API, you will not
see these fields in the return value, though they may have been set
in the Cloud Console."##),
Some(r##"Returns a budget. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. When reading from the API, you will not see these fields in the return value, though they may have been set in the Cloud Console."##),
"Details at http://byron.github.io/google-apis-rs/google_billingbudgets1_beta1_cli/billing-accounts_budgets-get",
vec![
(Some(r##"name"##),
None,
Some(r##"Required. Name of budget to get. Values are of the form
`billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(r##"Required. Name of budget to get. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(true),
Some(false)),
@@ -599,18 +591,12 @@ fn main() {
Some(false)),
]),
("budgets-list",
Some(r##"Returns a list of budgets for a billing account.
WARNING: There are some fields exposed on the Google Cloud Console that
aren't available on this API. When reading from the API, you will not
see these fields in the return value, though they may have been set
in the Cloud Console."##),
Some(r##"Returns a list of budgets for a billing account. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. When reading from the API, you will not see these fields in the return value, though they may have been set in the Cloud Console."##),
"Details at http://byron.github.io/google-apis-rs/google_billingbudgets1_beta1_cli/billing-accounts_budgets-list",
vec![
(Some(r##"parent"##),
None,
Some(r##"Required. Name of billing account to list budgets under. Values
are of the form `billingAccounts/{billingAccountId}`."##),
Some(r##"Required. Name of billing account to list budgets under. Values are of the form `billingAccounts/{billingAccountId}`."##),
Some(true),
Some(false)),
@@ -627,18 +613,12 @@ fn main() {
Some(false)),
]),
("budgets-patch",
Some(r##"Updates a budget and returns the updated budget.
WARNING: There are some fields exposed on the Google Cloud Console that
aren't available on this API. Budget fields that are not exposed in
this API will not be changed by this method."##),
Some(r##"Updates a budget and returns the updated budget. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. Budget fields that are not exposed in this API will not be changed by this method."##),
"Details at http://byron.github.io/google-apis-rs/google_billingbudgets1_beta1_cli/billing-accounts_budgets-patch",
vec![
(Some(r##"name"##),
None,
Some(r##"Output only. Resource name of the budget.
The resource name implies the scope of a budget. Values are of the form
`billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(r##"Output only. Resource name of the budget. The resource name implies the scope of a budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`."##),
Some(true),
Some(false)),
@@ -666,7 +646,7 @@ fn main() {
let mut app = App::new("billingbudgets1-beta1")
.author("Sebastian Thiel <byronimo@gmail.com>")
.version("1.0.14+20200704")
.version("2.0.0+20210326")
.about("The Cloud Billing Budget API stores Cloud Billing budgets, which define a budget plan and the rules to execute as spend is tracked against that plan.")
.after_help("All documentation details can be found at http://byron.github.io/google-apis-rs/google_billingbudgets1_beta1_cli")
.arg(Arg::with_name("url")
@@ -681,12 +661,7 @@ fn main() {
.takes_value(true))
.arg(Arg::with_name("debug")
.long("debug")
.help("Output all server communication to standard error. `tx` and `rx` are placed into the same stream.")
.multiple(false)
.takes_value(false))
.arg(Arg::with_name("debug-auth")
.long("debug-auth")
.help("Output all communication related to authentication to standard error. `tx` and `rx` are placed into the same stream.")
.help("Debug print all errors")
.multiple(false)
.takes_value(false));
@@ -734,13 +709,13 @@ fn main() {
let matches = app.get_matches();
let debug = matches.is_present("debug");
match Engine::new(matches) {
match Engine::new(matches).await {
Err(err) => {
exit_status = err.exit_code;
writeln!(io::stderr(), "{}", err).ok();
},
Ok(engine) => {
if let Err(doit_err) = engine.doit() {
if let Err(doit_err) = engine.doit().await {
exit_status = 1;
match doit_err {
DoitError::IoError(path, err) => {
@@ -759,4 +734,4 @@ fn main() {
}
std::process::exit(exit_status);
}
}