diff --git a/progenitor-impl/src/cli.rs b/progenitor-impl/src/cli.rs index 41fab5c..0a07091 100644 --- a/progenitor-impl/src/cli.rs +++ b/progenitor-impl/src/cli.rs @@ -177,18 +177,19 @@ impl Generator { &mut self, method: &crate::method::OperationMethod, ) -> CliOperation { + let maybe_body_arg = method.params.iter().find(|param| { + matches!(¶m.kind, OperationParameterKind::Body(_)) + // TODO not sure how to deal with raw bodies right now + && matches!(¶m.typ, OperationParameterType::Type(_)) + }); + + let mut full_body = true; + // Preprocess the body parameter (if there is one) to create an // iterator of top-level properties that can be represented as scalar // values. We use these to create `clap::Arg` structures and then to // build up the body parameter in the actual API call. - let body_params = method - .params - .iter() - .find(|param| { - matches!(¶m.kind, OperationParameterKind::Body(_)) - // TODO not sure how to deal with raw bodies right now - && matches!(¶m.typ, OperationParameterType::Type(_)) - }) + let body_params = maybe_body_arg .into_iter() .flat_map(|param| { let OperationParameterType::Type(type_id) = ¶m.typ else { @@ -251,6 +252,14 @@ impl Generator { prop_type.has_impl(TypeSpaceImpl::FromStr); let prop_name = prop_name.to_kebab_case(); + // If there's a required property that we can't + // represent as a scalar (and therefore as a + // CLI parameter), the user will be unable to + // specify the full body without a json file. + if required && !scalar { + full_body = false; + } + // println!( // "{}::{}: {}; scalar: {}; required: {}", // body_args.name(), @@ -289,9 +298,15 @@ impl Generator { let arg_name = param.name.to_kebab_case(); let required = match ¶m.kind { - OperationParameterKind::Path => true, - OperationParameterKind::Query(required) => *required, - OperationParameterKind::Header(required) => *required, + OperationParameterKind::Path => Volitionality::Required, + OperationParameterKind::Query(true) + | OperationParameterKind::Header(true) => { + Volitionality::Required + } + OperationParameterKind::Query(false) + | OperationParameterKind::Header(false) => { + Volitionality::Optional + } OperationParameterKind::Body(_) => unreachable!(), }; @@ -306,7 +321,12 @@ impl Generator { let body_args = body_params.iter().map( |(prop_name, required, description, prop_type)| { - clap_arg(prop_name, *required, description, prop_type) + let volitionality = if *required { + Volitionality::RequiredIfNoBody + } else { + Volitionality::Optional + }; + clap_arg(prop_name, volitionality, description, prop_type) }, ); @@ -314,6 +334,30 @@ impl Generator { // TODO parameter to output a body template (--body-template?) // TODO deal with all parameters? + let body_json_args = maybe_body_arg.map(|_| { + let help = "Path to a file that contains the full json body."; + let required = !full_body; + + quote! { + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + // Required if we can't turn the body into individual + // parameters. + .required(#required) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help(#help) + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX") + ) + } + }); + let about = method.summary.as_ref().map(|summary| { quote! { .about(#summary) @@ -336,6 +380,7 @@ impl Generator { #( .arg(#body_args) )* + #body_json_args #about #long_about } @@ -463,15 +508,39 @@ impl Generator { } }; + let body_json_args = maybe_body_arg.map(|body_param| { + let OperationParameterType::Type(body_type_id) = &body_param.typ + else { + unreachable!(); + }; + let body_type = self.type_space.get_type(body_type_id).unwrap(); + let body_type_ident = body_type.ident(); + quote! { + if let Some(value) = + matches.get_one::("json-body") + { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::<#body_type_ident>( + &body_txt, + ) + .unwrap(); + request = request.body(body_value); + } + } + }); + let execute_fn = quote! { pub async fn #fn_name(&self, matches: &clap::ArgMatches) // -> // Result, Error<#error_type>> { let mut request = self.client.#op_name(); + #body_json_args #( #args )* #( #body_args )* + // Call the override function. // TODO don't want to unwrap. self.over .#fn_name(matches, &mut request) @@ -503,9 +572,15 @@ impl Generator { } } +enum Volitionality { + Optional, + Required, + RequiredIfNoBody, +} + fn clap_arg( arg_name: &str, - required: bool, + volitionality: Volitionality, description: &Option, arg_type: &Type, ) -> TokenStream { @@ -559,11 +634,19 @@ fn clap_arg( } }; + let required = match volitionality { + Volitionality::Optional => quote! { .required(false) }, + Volitionality::Required => quote! { .required(true) }, + Volitionality::RequiredIfNoBody => { + quote! { .required_unless_present("json-body") } + } + }; + quote! { clap::Arg::new(#arg_name) .long(#arg_name) - .required(#required) .value_parser(#value_parser) + #required #help } } diff --git a/progenitor-impl/src/method.rs b/progenitor-impl/src/method.rs index ab50ca6..646ed33 100644 --- a/progenitor-impl/src/method.rs +++ b/progenitor-impl/src/method.rs @@ -729,9 +729,8 @@ impl Generator { let page = page.into_inner(); // Create a stream from the items of the first page. - let first = futures::stream::iter( - page.items.into_iter().map(Ok) - ); + let first = + futures::stream::iter(page.items).map(Ok); // We unfold subsequent pages using page.next_page // as the seed value. Each iteration returns its @@ -756,11 +755,8 @@ impl Generator { let page = page.into_inner(); Some(( futures::stream::iter( - page - .items - .into_iter() - .map(Ok), - ), + page.items + ).map(Ok), page.next_page, )) }) @@ -1725,9 +1721,8 @@ impl Generator { let page = page.into_inner(); // Create a stream from the first page of items. - let first = futures::stream::iter( - page.items.into_iter().map(Ok) - ); + let first = + futures::stream::iter(page.items).map(Ok); // We unfold subsequent pages using page.next_page // as the seed value. Each iteration returns its @@ -1753,11 +1748,8 @@ impl Generator { let page = page.into_inner(); Some(( futures::stream::iter( - page - .items - .into_iter() - .map(Ok), - ), + page.items + ).map(Ok), (page.next_page, next), )) }) diff --git a/progenitor-impl/tests/output/buildomat-cli.out b/progenitor-impl/tests/output/buildomat-cli.out index 3e56cdf..1f09219 100644 --- a/progenitor-impl/tests/output/buildomat-cli.out +++ b/progenitor-impl/tests/output/buildomat-cli.out @@ -43,8 +43,8 @@ impl Cli { clap::Command::new("").arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) } @@ -57,14 +57,28 @@ impl Cli { .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("script") .long("script") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -73,14 +87,14 @@ impl Cli { .arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) .arg( clap::Arg::new("minseq") .long("minseq") - .required(false) - .value_parser(clap::value_parser!(u32)), + .value_parser(clap::value_parser!(u32)) + .required(false), ) } @@ -88,8 +102,8 @@ impl Cli { clap::Command::new("").arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) } @@ -98,24 +112,39 @@ impl Cli { .arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) .arg( clap::Arg::new("output") .long("output") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) } pub fn cli_user_create() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("name") - .long("name") - .required(true) - .value_parser(clap::value_parser!(String)), - ) + clap::Command::new("") + .arg( + clap::Arg::new("name") + .long("name") + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_whoami() -> clap::Command { @@ -127,14 +156,28 @@ impl Cli { .arg( clap::Arg::new("bootstrap") .long("bootstrap") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("token") .long("token") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -147,26 +190,40 @@ impl Cli { .arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) .arg( clap::Arg::new("payload") .long("payload") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("stream") .long("stream") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("time") .long("time") - .required(true) - .value_parser(clap::value_parser!(chrono::DateTime)), + .value_parser(clap::value_parser!(chrono::DateTime)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -174,8 +231,8 @@ impl Cli { clap::Command::new("").arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) } @@ -184,14 +241,28 @@ impl Cli { .arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) .arg( clap::Arg::new("failed") .long("failed") - .required(true) - .value_parser(clap::value_parser!(bool)), + .value_parser(clap::value_parser!(bool)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -200,20 +271,34 @@ impl Cli { .arg( clap::Arg::new("task") .long("task") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(true), ) .arg( clap::Arg::new("path") .long("path") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("size") .long("size") + .value_parser(clap::value_parser!(i64)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(i64)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -356,6 +441,12 @@ impl Cli { pub async fn execute_task_submit(&self, matches: &clap::ArgMatches) { let mut request = self.client.task_submit(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("name") { request = request.body_map(|body| body.name(value.clone())) } @@ -448,6 +539,12 @@ impl Cli { pub async fn execute_user_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.user_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("name") { request = request.body_map(|body| body.name(value.clone())) } @@ -482,6 +579,12 @@ impl Cli { pub async fn execute_worker_bootstrap(&self, matches: &clap::ArgMatches) { let mut request = self.client.worker_bootstrap(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("bootstrap") { request = request.body_map(|body| body.bootstrap(value.clone())) } @@ -522,6 +625,12 @@ impl Cli { pub async fn execute_worker_task_append(&self, matches: &clap::ArgMatches) { let mut request = self.client.worker_task_append(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("task") { request = request.task(value.clone()); } @@ -574,6 +683,12 @@ impl Cli { pub async fn execute_worker_task_complete(&self, matches: &clap::ArgMatches) { let mut request = self.client.worker_task_complete(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("task") { request = request.task(value.clone()); } @@ -598,6 +713,12 @@ impl Cli { pub async fn execute_worker_task_add_output(&self, matches: &clap::ArgMatches) { let mut request = self.client.worker_task_add_output(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("task") { request = request.task(value.clone()); } diff --git a/progenitor-impl/tests/output/keeper-cli.out b/progenitor-impl/tests/output/keeper-cli.out index a46827f..ba3405e 100644 --- a/progenitor-impl/tests/output/keeper-cli.out +++ b/progenitor-impl/tests/output/keeper-cli.out @@ -24,21 +24,35 @@ impl Cli { .arg( clap::Arg::new("authorization") .long("authorization") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("Authorization header (bearer token)"), ) .arg( clap::Arg::new("host") .long("host") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("key") .long("key") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } @@ -46,8 +60,8 @@ impl Cli { clap::Command::new("").arg( clap::Arg::new("authorization") .long("authorization") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("Authorization header (bearer token)"), ) } @@ -56,8 +70,8 @@ impl Cli { clap::Command::new("").arg( clap::Arg::new("authorization") .long("authorization") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("Authorization header (bearer token)"), ) } @@ -67,38 +81,67 @@ impl Cli { .arg( clap::Arg::new("authorization") .long("authorization") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("Authorization header (bearer token)"), ) .arg( clap::Arg::new("duration-millis") .long("duration-millis") - .required(true) - .value_parser(clap::value_parser!(i32)), + .value_parser(clap::value_parser!(i32)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("end-time") .long("end-time") - .required(true) - .value_parser(clap::value_parser!(chrono::DateTime)), + .value_parser(clap::value_parser!(chrono::DateTime)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("exit-status") .long("exit-status") + .value_parser(clap::value_parser!(i32)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(i32)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } pub fn cli_report_output() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("authorization") - .long("authorization") - .required(true) - .value_parser(clap::value_parser!(String)) - .help("Authorization header (bearer token)"), - ) + clap::Command::new("") + .arg( + clap::Arg::new("authorization") + .long("authorization") + .value_parser(clap::value_parser!(String)) + .required(true) + .help("Authorization header (bearer token)"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_report_start() -> clap::Command { @@ -106,21 +149,35 @@ impl Cli { .arg( clap::Arg::new("authorization") .long("authorization") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("Authorization header (bearer token)"), ) .arg( clap::Arg::new("script") .long("script") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("start-time") .long("start-time") + .value_parser(clap::value_parser!(chrono::DateTime)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(chrono::DateTime)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) } } @@ -155,6 +212,12 @@ impl Cli { pub async fn execute_enrol(&self, matches: &clap::ArgMatches) { let mut request = self.client.enrol(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("authorization") { request = request.authorization(value.clone()); } @@ -219,6 +282,12 @@ impl Cli { pub async fn execute_report_finish(&self, matches: &clap::ArgMatches) { let mut request = self.client.report_finish(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("authorization") { request = request.authorization(value.clone()); } @@ -251,6 +320,12 @@ impl Cli { pub async fn execute_report_output(&self, matches: &clap::ArgMatches) { let mut request = self.client.report_output(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("authorization") { request = request.authorization(value.clone()); } @@ -271,6 +346,12 @@ impl Cli { pub async fn execute_report_start(&self, matches: &clap::ArgMatches) { let mut request = self.client.report_start(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("authorization") { request = request.authorization(value.clone()); } diff --git a/progenitor-impl/tests/output/nexus-builder-tagged.out b/progenitor-impl/tests/output/nexus-builder-tagged.out index a92d657..e3e8a35 100644 --- a/progenitor-impl/tests/output/nexus-builder-tagged.out +++ b/progenitor-impl/tests/output/nexus-builder-tagged.out @@ -21982,7 +21982,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -21997,7 +21997,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -22489,7 +22489,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -22504,7 +22504,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -23105,7 +23105,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -23120,7 +23120,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -23646,7 +23646,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -23661,7 +23661,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -24182,7 +24182,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -24197,7 +24197,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -24374,7 +24374,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -24389,7 +24389,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -24860,7 +24860,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -24875,7 +24875,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -25362,7 +25362,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -25377,7 +25377,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -26028,7 +26028,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -26043,7 +26043,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -27424,7 +27424,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -27439,7 +27439,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -27909,7 +27909,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -27924,7 +27924,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -28749,7 +28749,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -28764,7 +28764,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -29446,7 +29446,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -29461,7 +29461,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -30192,7 +30192,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -30207,7 +30207,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -30890,7 +30890,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -30905,7 +30905,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31139,7 +31139,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31154,7 +31154,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31395,7 +31395,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31410,7 +31410,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31552,7 +31552,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31567,7 +31567,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32077,7 +32077,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32092,7 +32092,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32427,7 +32427,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32442,7 +32442,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32584,7 +32584,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32599,7 +32599,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32800,7 +32800,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32815,7 +32815,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33034,7 +33034,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33049,7 +33049,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33191,7 +33191,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33206,7 +33206,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33535,7 +33535,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33550,7 +33550,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33964,7 +33964,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33979,7 +33979,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -34297,7 +34297,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -34312,7 +34312,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -34830,7 +34830,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -34845,7 +34845,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -35046,7 +35046,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -35061,7 +35061,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -35409,7 +35409,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -35424,7 +35424,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36168,7 +36168,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36183,7 +36183,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36403,7 +36403,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36418,7 +36418,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36601,7 +36601,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36616,7 +36616,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36758,7 +36758,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36773,7 +36773,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36953,7 +36953,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36968,7 +36968,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -37453,7 +37453,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -37468,7 +37468,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -37971,7 +37971,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -37986,7 +37986,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -39066,7 +39066,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -39081,7 +39081,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -39681,7 +39681,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -39696,7 +39696,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40395,7 +40395,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40410,7 +40410,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40553,7 +40553,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40568,7 +40568,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40922,7 +40922,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40937,7 +40937,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) diff --git a/progenitor-impl/tests/output/nexus-builder.out b/progenitor-impl/tests/output/nexus-builder.out index d4491b7..5878b93 100644 --- a/progenitor-impl/tests/output/nexus-builder.out +++ b/progenitor-impl/tests/output/nexus-builder.out @@ -21776,7 +21776,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -21791,7 +21791,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -22283,7 +22283,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -22298,7 +22298,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -22899,7 +22899,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -22914,7 +22914,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -23440,7 +23440,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -23455,7 +23455,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -23976,7 +23976,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -23991,7 +23991,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -24168,7 +24168,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -24183,7 +24183,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -24654,7 +24654,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -24669,7 +24669,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -25156,7 +25156,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -25171,7 +25171,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -25822,7 +25822,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -25837,7 +25837,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -27218,7 +27218,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -27233,7 +27233,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -27703,7 +27703,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -27718,7 +27718,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -28543,7 +28543,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -28558,7 +28558,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -29240,7 +29240,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -29255,7 +29255,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -29986,7 +29986,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -30001,7 +30001,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -30684,7 +30684,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -30699,7 +30699,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -30933,7 +30933,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -30948,7 +30948,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31189,7 +31189,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31204,7 +31204,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31346,7 +31346,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31361,7 +31361,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -31871,7 +31871,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -31886,7 +31886,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32221,7 +32221,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32236,7 +32236,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32378,7 +32378,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32393,7 +32393,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32594,7 +32594,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32609,7 +32609,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32828,7 +32828,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -32843,7 +32843,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -32985,7 +32985,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33000,7 +33000,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33329,7 +33329,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33344,7 +33344,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -33758,7 +33758,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -33773,7 +33773,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -34091,7 +34091,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -34106,7 +34106,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -34624,7 +34624,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -34639,7 +34639,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -34840,7 +34840,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -34855,7 +34855,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -35203,7 +35203,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -35218,7 +35218,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -35962,7 +35962,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -35977,7 +35977,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36197,7 +36197,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36212,7 +36212,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36395,7 +36395,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36410,7 +36410,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36552,7 +36552,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36567,7 +36567,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -36747,7 +36747,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -36762,7 +36762,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -37247,7 +37247,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -37262,7 +37262,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -37765,7 +37765,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -37780,7 +37780,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -38860,7 +38860,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -38875,7 +38875,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -39475,7 +39475,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -39490,7 +39490,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40189,7 +40189,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40204,7 +40204,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40347,7 +40347,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40362,7 +40362,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) @@ -40716,7 +40716,7 @@ pub mod builder { self.send() .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold( (page.next_page, next), |(next_page, next)| async { @@ -40731,7 +40731,7 @@ pub mod builder { .map_ok(|page| { let page = page.into_inner(); Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), + futures::stream::iter(page.items).map(Ok), (page.next_page, next), )) }) diff --git a/progenitor-impl/tests/output/nexus-cli.out b/progenitor-impl/tests/output/nexus-cli.out index b0e0da5..5cc4092 100644 --- a/progenitor-impl/tests/output/nexus-cli.out +++ b/progenitor-impl/tests/output/nexus-cli.out @@ -222,8 +222,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a disk by id") .long_about("Use `GET /v1/disks/{disk}` instead") @@ -234,8 +234,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch an image by id") } @@ -245,8 +245,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch an instance by id") } @@ -256,8 +256,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a network interface by id") } @@ -267,8 +267,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch an organization by id") .long_about("Use `GET /v1/organizations/{organization}` instead") @@ -279,8 +279,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a project by id") .long_about("Use `GET /v1/projects/{project}` instead") @@ -291,8 +291,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a snapshot by id") } @@ -302,8 +302,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a route by id") } @@ -313,8 +313,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Get a router by id") } @@ -324,8 +324,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a subnet by id") } @@ -335,8 +335,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a VPC") } @@ -346,8 +346,22 @@ impl Cli { .arg( clap::Arg::new("client-id") .long("client-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Start an OAuth 2.0 Device Authorization Grant") .long_about( @@ -362,8 +376,22 @@ impl Cli { .arg( clap::Arg::new("user-code") .long("user-code") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Confirm an OAuth 2.0 Device Authorization Grant") .long_about( @@ -378,20 +406,34 @@ impl Cli { .arg( clap::Arg::new("client-id") .long("client-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("device-code") .long("device-code") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("grant-type") .long("grant-type") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Request a device access token") .long_about( @@ -405,31 +447,46 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List groups") } pub fn cli_login_spoof() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("username") - .long("username") - .required(true) - .value_parser(clap::value_parser!(String)), - ) + clap::Command::new("") + .arg( + clap::Arg::new("username") + .long("username") + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_login_local() -> clap::Command { @@ -437,20 +494,34 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("password") .long("password") - .required(true) - .value_parser(clap::value_parser!(types::Password)), + .value_parser(clap::value_parser!(types::Password)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("username") .long("username") - .required(true) - .value_parser(clap::value_parser!(types::UserId)), + .value_parser(clap::value_parser!(types::UserId)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Authenticate a user (i.e., log in) via username and password") } @@ -460,14 +531,14 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("provider-name") .long("provider-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Prompt user login") .long_about( @@ -481,14 +552,14 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("provider-name") .long("provider-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Authenticate a user (i.e., log in) via SAML") } @@ -502,14 +573,13 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -517,7 +587,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List organizations") .long_about("Use `GET /v1/organizations` instead") @@ -528,14 +599,28 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create an organization") .long_about("Use `POST /v1/organizations` instead") @@ -546,8 +631,8 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .about("Fetch an organization") @@ -559,21 +644,35 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update an organization") .long_about("Use `PUT /v1/organizations/{organization}` instead") @@ -584,8 +683,8 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .about("Delete an organization") @@ -597,8 +696,8 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .about("Fetch an organization's IAM policy") @@ -610,10 +709,24 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Update an organization's IAM policy") .long_about("Use `PUT /v1/organizations/{organization}/policy` instead") } @@ -623,21 +736,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -645,7 +757,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List projects") .long_about("Use `GET /v1/projects` instead") @@ -656,21 +769,35 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a project") .long_about("Use `POST /v1/projects` instead") @@ -681,15 +808,15 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .about("Fetch a project") @@ -701,28 +828,42 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a project") .long_about("Use `PUT /v1/projects/{project}` instead") @@ -733,15 +874,15 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .about("Delete a project") @@ -753,34 +894,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List disks") .long_about("Use `GET /v1/disks` instead") @@ -791,36 +932,50 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("size") .long("size") - .required(true) .value_parser(clap::value_parser!(types::ByteCount)) + .required_unless_present("json-body") .help("total size of the Disk in bytes"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Use `POST /v1/disks` instead") } @@ -829,20 +984,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("disk-name") .long("disk-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a disk") .long_about("Use `GET /v1/disks/{disk}` instead") @@ -853,20 +1008,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("disk-name") .long("disk-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Use `DELETE /v1/disks/{disk}` instead") } @@ -876,25 +1031,24 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("disk-name") .long("disk-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("metric-name") .long("metric-name") - .required(true) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::DiskMetricName::Activated.to_string(), @@ -905,27 +1059,28 @@ impl Cli { types::DiskMetricName::WriteBytes.to_string(), ]), |s| types::DiskMetricName::try_from(s).unwrap(), - )), + )) + .required(true), ) .arg( clap::Arg::new("end-time") .long("end-time") - .required(false) .value_parser(clap::value_parser!(chrono::DateTime)) + .required(false) .help("An exclusive end time of metrics."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("start-time") .long("start-time") - .required(false) .value_parser(clap::value_parser!(chrono::DateTime)) + .required(false) .help("An inclusive start time of metrics."), ) .about("Fetch disk metrics") @@ -936,34 +1091,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List images") .long_about( @@ -977,28 +1132,42 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create an image") .long_about("Create a new image in a project.") @@ -1009,20 +1178,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("image-name") .long("image-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch an image") .long_about("Fetch the details for a specific image in a project.") @@ -1033,20 +1202,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("image-name") .long("image-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete an image") .long_about( @@ -1061,34 +1230,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List instances") } @@ -1098,65 +1267,79 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("hostname") .long("hostname") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("memory") .long("memory") - .required(true) - .value_parser(clap::value_parser!(types::ByteCount)), + .value_parser(clap::value_parser!(types::ByteCount)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("ncpus") .long("ncpus") - .required(true) - .value_parser(clap::value_parser!(types::InstanceCpuCount)), + .value_parser(clap::value_parser!(types::InstanceCpuCount)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("start") .long("start") - .required(false) .value_parser(clap::value_parser!(bool)) + .required(false) .help("Should this instance be started upon creation; true by default."), ) .arg( clap::Arg::new("user-data") .long("user-data") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help( "User data for instance initialization systems (such as cloud-init). Must \ be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and / \ characters with padding). Maximum 32 KiB unencoded data.", ), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create an instance") .long_about("Use `POST /v1/instances` instead") } @@ -1166,20 +1349,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch an instance") .long_about("Use `GET /v1/instances/{instance}` instead") @@ -1190,20 +1373,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete an instance") } @@ -1213,38 +1396,38 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List an instance's disks") .long_about("Use `GET /v1/instances/{instance}/disks` instead") @@ -1255,26 +1438,40 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Attach a disk to an instance") .long_about("Use `POST /v1/instances/{instance}/disks/attach` instead") @@ -1285,26 +1482,40 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Detach a disk from an instance") .long_about("Use `POST /v1/disks/{disk}/detach` instead") @@ -1315,20 +1526,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("List external IP addresses") } @@ -1338,26 +1549,40 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("dst-sled-id") .long("dst-sled-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Migrate an instance") .long_about("Use `POST /v1/instances/{instance}/migrate` instead") @@ -1368,38 +1593,38 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List network interfaces") } @@ -1409,32 +1634,32 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("ip") .long("ip") - .required(false) .value_parser(clap::value_parser!(std::net::IpAddr)) + .required(false) .help( "The IP address for the interface. One will be auto-assigned if not \ provided.", @@ -1443,23 +1668,37 @@ impl Cli { .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("subnet-name") .long("subnet-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body") .help("The VPC Subnet in which to create the interface."), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body") .help("The VPC in which to create the interface."), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create a network interface") } @@ -1468,26 +1707,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("interface-name") .long("interface-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a network interface") } @@ -1497,44 +1736,44 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("interface-name") .long("interface-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") - .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(false), ) .arg( clap::Arg::new("primary") .long("primary") - .required(false) .value_parser(clap::value_parser!(bool)) + .required(false) .help( "Make a secondary interface the instance's primary interface.\n\nIf \ applied to a secondary interface, that interface will become the primary \ @@ -1546,6 +1785,20 @@ impl Cli { error.", ), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Update a network interface") } @@ -1554,26 +1807,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("interface-name") .long("interface-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a network interface") .long_about( @@ -1588,20 +1841,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Reboot an instance") .long_about("Use `POST /v1/instances/{instance}/reboot` instead") @@ -1612,26 +1865,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("from-start") .long("from-start") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Character index in the serial buffer from which to read, counting the \ bytes output since instance start. If this is not provided, \ @@ -1642,8 +1895,8 @@ impl Cli { .arg( clap::Arg::new("max-bytes") .long("max-bytes") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Maximum number of bytes of buffered serial console contents to return. \ If the requested range runs to the end of the available buffer, the data \ @@ -1653,8 +1906,8 @@ impl Cli { .arg( clap::Arg::new("most-recent") .long("most-recent") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Character index in the serial buffer from which to read, counting \ *backward* from the most recently buffered data retrieved from the \ @@ -1670,20 +1923,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Connect to an instance's serial console") .long_about("Use `GET /v1/instances/{instance}/serial-console/stream` instead") @@ -1694,20 +1947,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Boot an instance") .long_about("Use `POST /v1/instances/{instance}/start` instead") @@ -1718,20 +1971,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("instance-name") .long("instance-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Halt an instance") .long_about("Use `POST /v1/instances/{instance}/stop` instead") @@ -1742,15 +1995,15 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .about("Fetch a project's IAM policy") @@ -1762,17 +2015,31 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Update a project's IAM policy") } @@ -1781,34 +2048,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List snapshots") } @@ -1818,35 +2085,49 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("disk") .long("disk") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body") .help("The name of the disk to be snapshotted"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a snapshot") .long_about("Creates a point-in-time snapshot from a disk.") @@ -1857,20 +2138,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("snapshot-name") .long("snapshot-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a snapshot") } @@ -1880,20 +2161,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("snapshot-name") .long("snapshot-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a snapshot") } @@ -1903,34 +2184,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List VPCs") } @@ -1940,34 +2221,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The organization's unique name."), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The project's unique name within the organization."), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("dns-name") .long("dns-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("ipv6-prefix") .long("ipv6-prefix") - .required(false) .value_parser(clap::value_parser!(types::Ipv6Net)) + .required(false) .help( "The IPv6 prefix for this VPC.\n\nAll IPv6 subnets created from this VPC \ must be taken from this range, which sould be a Unique Local Address in \ @@ -1978,8 +2259,22 @@ impl Cli { .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a VPC") } @@ -1989,20 +2284,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a VPC") } @@ -2012,38 +2307,52 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("dns-name") .long("dns-name") - .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a VPC") } @@ -2053,20 +2362,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a VPC") } @@ -2076,20 +2385,20 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("List firewall rules") } @@ -2099,20 +2408,34 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") + .value_parser(clap::value_parser!(types::Name)) + .required(true), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Replace firewall rules") } @@ -2122,38 +2445,38 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List routers") } @@ -2163,32 +2486,46 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a router") } @@ -2198,26 +2535,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Get a router") } @@ -2227,38 +2564,52 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a router") } @@ -2268,26 +2619,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a router") } @@ -2297,44 +2648,44 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List routes") .long_about("List the routes associated with a router in a particular VPC.") @@ -2345,38 +2696,52 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a router") } @@ -2386,32 +2751,32 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("route-name") .long("route-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a route") } @@ -2421,44 +2786,58 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("route-name") .long("route-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") - .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a route") } @@ -2468,32 +2847,32 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("router-name") .long("router-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("route-name") .long("route-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a route") } @@ -2503,38 +2882,38 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List subnets") } @@ -2544,32 +2923,32 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("ipv4-block") .long("ipv4-block") - .required(true) .value_parser(clap::value_parser!(types::Ipv4Net)) + .required_unless_present("json-body") .help( "The IPv4 address range for this subnet.\n\nIt must be allocated from an \ RFC 1918 private address range, and must not overlap with any other \ @@ -2579,8 +2958,8 @@ impl Cli { .arg( clap::Arg::new("ipv6-block") .long("ipv6-block") - .required(false) .value_parser(clap::value_parser!(types::Ipv6Net)) + .required(false) .help( "The IPv6 address range for this subnet.\n\nIt must be allocated from the \ RFC 4193 Unique Local Address range, with the prefix equal to the parent \ @@ -2591,8 +2970,22 @@ impl Cli { .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a subnet") } @@ -2602,26 +2995,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("subnet-name") .long("subnet-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a subnet") } @@ -2631,38 +3024,52 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("subnet-name") .long("subnet-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a subnet") } @@ -2672,26 +3079,26 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("subnet-name") .long("subnet-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a subnet") } @@ -2701,44 +3108,44 @@ impl Cli { .arg( clap::Arg::new("organization-name") .long("organization-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("project-name") .long("project-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("vpc-name") .long("vpc-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("subnet-name") .long("subnet-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List network interfaces") } @@ -2748,7 +3155,22 @@ impl Cli { } pub fn cli_policy_update() -> clap::Command { - clap::Command::new("").about("Update the current silo's IAM policy") + clap::Command::new("") + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) + .about("Update the current silo's IAM policy") } pub fn cli_role_list() -> clap::Command { @@ -2756,8 +3178,8 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .about("List built-in roles") @@ -2768,8 +3190,8 @@ impl Cli { .arg( clap::Arg::new("role-name") .long("role-name") - .required(true) .value_parser(clap::value_parser!(String)) + .required(true) .help("The built-in role's unique name."), ) .about("Fetch a built-in role") @@ -2784,20 +3206,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("Fetch the silo\u{a0}groups the current user belongs to") } @@ -2807,20 +3229,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List SSH public keys") .long_about("Lists SSH public keys for the currently authenticated user.") @@ -2831,22 +3253,36 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("public-key") .long("public-key") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("SSH public key, e.g., `\"ssh-ed25519 AAAAC3NzaC...\"`"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create an SSH public key") .long_about("Create an SSH public key for the currently authenticated user.") } @@ -2856,8 +3292,8 @@ impl Cli { .arg( clap::Arg::new("ssh-key-name") .long("ssh-key-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch an SSH public key") .long_about("Fetch an SSH public key associated with the currently authenticated user.") @@ -2868,8 +3304,8 @@ impl Cli { .arg( clap::Arg::new("ssh-key-name") .long("ssh-key-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete an SSH public key") .long_about( @@ -2882,8 +3318,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a system-wide image by id") } @@ -2893,8 +3329,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch an IP pool by id") } @@ -2904,8 +3340,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a silo by id") } @@ -2915,20 +3351,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List system-wide certificates") .long_about( @@ -2943,27 +3379,41 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("service") .long("service") - .required(true) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::ServiceUsingCertificate::ExternalApi.to_string(), ]), |s| types::ServiceUsingCertificate::try_from(s).unwrap(), )) + .required_unless_present("json-body") .help("The service using this certificate"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create a new system-wide x.509 certificate.") .long_about( "This certificate is automatically used by the Oxide Control plane to serve \ @@ -2976,8 +3426,8 @@ impl Cli { .arg( clap::Arg::new("certificate") .long("certificate") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .about("Fetch a certificate") .long_about("Returns the details of a specific certificate") @@ -2988,8 +3438,8 @@ impl Cli { .arg( clap::Arg::new("certificate") .long("certificate") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .about("Delete a certificate") .long_about("Permanently delete a certificate. This operation cannot be undone.") @@ -3000,20 +3450,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List physical disks") } @@ -3023,20 +3473,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List racks") } @@ -3046,8 +3496,8 @@ impl Cli { .arg( clap::Arg::new("rack-id") .long("rack-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The rack's unique ID."), ) .about("Fetch a rack") @@ -3058,20 +3508,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List sleds") } @@ -3081,8 +3531,8 @@ impl Cli { .arg( clap::Arg::new("sled-id") .long("sled-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The sled's unique ID."), ) .about("Fetch a sled") @@ -3093,27 +3543,27 @@ impl Cli { .arg( clap::Arg::new("sled-id") .long("sled-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The sled's unique ID."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List physical disks attached to sleds") } @@ -3123,20 +3573,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List system-wide images") .long_about( @@ -3150,14 +3600,28 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a system-wide image") .long_about( @@ -3171,8 +3635,8 @@ impl Cli { .arg( clap::Arg::new("image-name") .long("image-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch a system-wide image") .long_about("Returns the details of a specific system-wide image.") @@ -3183,8 +3647,8 @@ impl Cli { .arg( clap::Arg::new("image-name") .long("image-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete a system-wide image") .long_about( @@ -3199,14 +3663,13 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -3214,7 +3677,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List IP pools") } @@ -3224,14 +3688,28 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create an IP pool") } @@ -3241,8 +3719,8 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Fetch an IP pool") } @@ -3252,20 +3730,34 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update an IP Pool") } @@ -3275,8 +3767,8 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .about("Delete an IP Pool") } @@ -3286,14 +3778,14 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .about("List ranges for an IP pool") @@ -3305,8 +3797,22 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Add a range to an IP pool") } @@ -3316,8 +3822,22 @@ impl Cli { .arg( clap::Arg::new("pool-name") .long("pool-name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required(true), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Remove a range from an IP pool") } @@ -3331,8 +3851,8 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .about("List ranges for the IP pool used for Oxide services.") @@ -3340,11 +3860,41 @@ impl Cli { } pub fn cli_ip_pool_service_range_add() -> clap::Command { - clap::Command::new("").about("Add a range to an IP pool used for Oxide services.") + clap::Command::new("") + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) + .about("Add a range to an IP pool used for Oxide services.") } pub fn cli_ip_pool_service_range_remove() -> clap::Command { - clap::Command::new("").about("Remove a range from an IP pool used for Oxide services.") + clap::Command::new("") + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) + .about("Remove a range from an IP pool used for Oxide services.") } pub fn cli_system_metric() -> clap::Command { @@ -3352,7 +3902,6 @@ impl Cli { .arg( clap::Arg::new("metric-name") .long("metric-name") - .required(true) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::SystemMetricName::VirtualDiskSpaceProvisioned.to_string(), @@ -3360,41 +3909,42 @@ impl Cli { types::SystemMetricName::RamProvisioned.to_string(), ]), |s| types::SystemMetricName::try_from(s).unwrap(), - )), + )) + .required(true), ) .arg( clap::Arg::new("end-time") .long("end-time") - .required(false) .value_parser(clap::value_parser!(chrono::DateTime)) + .required(false) .help("An exclusive end time of metrics."), ) .arg( clap::Arg::new("id") .long("id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The UUID of the container being queried"), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("page-token") .long("page-token") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help("Token returned by previous call to retrieve the subsequent page"), ) .arg( clap::Arg::new("start-time") .long("start-time") - .required(false) .value_parser(clap::value_parser!(chrono::DateTime)) + .required(false) .help("An inclusive start time of metrics."), ) .about("Access metrics data") @@ -3405,7 +3955,22 @@ impl Cli { } pub fn cli_system_policy_update() -> clap::Command { - clap::Command::new("").about("Update the top-level IAM policy") + clap::Command::new("") + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) + .about("Update the top-level IAM policy") } pub fn cli_saga_list() -> clap::Command { @@ -3413,20 +3978,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List sagas") } @@ -3436,8 +4001,8 @@ impl Cli { .arg( clap::Arg::new("saga-id") .long("saga-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a saga") } @@ -3447,14 +4012,13 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -3462,7 +4026,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List silos") .long_about("Lists silos that are discoverable based on the current permissions.") @@ -3473,8 +4038,8 @@ impl Cli { .arg( clap::Arg::new("admin-group-name") .long("admin-group-name") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help( "If set, this group will be created during Silo creation and granted the \ \"Silo Admin\" role. Identity providers can assert that users belong to \ @@ -3487,32 +4052,46 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("discoverable") .long("discoverable") - .required(true) - .value_parser(clap::value_parser!(bool)), + .value_parser(clap::value_parser!(bool)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("identity-mode") .long("identity-mode") - .required(true) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::SiloIdentityMode::SamlJit.to_string(), types::SiloIdentityMode::LocalOnly.to_string(), ]), |s| types::SiloIdentityMode::try_from(s).unwrap(), - )), + )) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a silo") } @@ -3522,8 +4101,8 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .about("Fetch a silo") @@ -3535,8 +4114,8 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .about("Delete a silo") @@ -3548,27 +4127,27 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List a silo's IDPs") } @@ -3578,17 +4157,31 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("external-id") .long("external-id") - .required(true) .value_parser(clap::value_parser!(types::UserId)) + .required_unless_present("json-body") .help("username used to log in"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create a user") .long_about( "Users can only be created in Silos with `provision_type` == `Fixed`. Otherwise, \ @@ -3602,15 +4195,15 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("user-id") .long("user-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The user's internal id"), ) .about("Delete a user") @@ -3621,17 +4214,31 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("user-id") .long("user-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The user's internal id"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Set or invalidate a user's password") .long_about( "Passwords can only be updated for users in Silos with identity mode `LocalOnly`.", @@ -3643,28 +4250,28 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("acs-url") .long("acs-url") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("service provider endpoint where the response will be sent"), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("group-attribute-name") .long("group-attribute-name") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help( "If set, SAML attributes with this name will be considered to denote a \ user's group membership, where the attribute value(s) should be a \ @@ -3674,37 +4281,51 @@ impl Cli { .arg( clap::Arg::new("idp-entity-id") .long("idp-entity-id") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("idp's entity id"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("slo-url") .long("slo-url") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("service provider endpoint where the idp should send log out requests"), ) .arg( clap::Arg::new("sp-client-id") .long("sp-client-id") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("sp's client id"), ) .arg( clap::Arg::new("technical-contact-email") .long("technical-contact-email") - .required(true) .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body") .help("customer's technical contact for saml configuration"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create a SAML IDP") } @@ -3713,15 +4334,15 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("provider-name") .long("provider-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The SAML identity provider's name"), ) .about("Fetch a SAML IDP") @@ -3732,8 +4353,8 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .about("Fetch a silo's IAM policy") @@ -3744,10 +4365,24 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Update a silo's IAM policy") } @@ -3756,27 +4391,27 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List users in a silo") } @@ -3786,15 +4421,15 @@ impl Cli { .arg( clap::Arg::new("silo-name") .long("silo-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The silo's unique name."), ) .arg( clap::Arg::new("user-id") .long("user-id") - .required(true) .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true) .help("The user's internal id"), ) .about("Fetch a user") @@ -3805,20 +4440,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameSortMode::NameAscending.to_string(), ]), |s| types::NameSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List built-in users") } @@ -3828,8 +4463,8 @@ impl Cli { .arg( clap::Arg::new("user-name") .long("user-name") - .required(true) .value_parser(clap::value_parser!(types::Name)) + .required(true) .help("The built-in user's unique name."), ) .about("Fetch a built-in user") @@ -3840,8 +4475,8 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .about("List timeseries schema") @@ -3852,20 +4487,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List users") } @@ -3875,26 +4510,25 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -3902,7 +4536,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List disks") } @@ -3912,34 +4547,48 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("size") .long("size") - .required(true) .value_parser(clap::value_parser!(types::ByteCount)) + .required_unless_present("json-body") .help("total size of the Disk in bytes"), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create a disk") } @@ -3948,20 +4597,20 @@ impl Cli { .arg( clap::Arg::new("disk") .long("disk") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Fetch a disk") } @@ -3971,20 +4620,20 @@ impl Cli { .arg( clap::Arg::new("disk") .long("disk") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Delete a disk") } @@ -3994,26 +4643,25 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -4021,7 +4669,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List instances") } @@ -4031,63 +4680,77 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("hostname") .long("hostname") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("memory") .long("memory") - .required(true) - .value_parser(clap::value_parser!(types::ByteCount)), + .value_parser(clap::value_parser!(types::ByteCount)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("ncpus") .long("ncpus") - .required(true) - .value_parser(clap::value_parser!(types::InstanceCpuCount)), + .value_parser(clap::value_parser!(types::InstanceCpuCount)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("start") .long("start") - .required(false) .value_parser(clap::value_parser!(bool)) + .required(false) .help("Should this instance be started upon creation; true by default."), ) .arg( clap::Arg::new("user-data") .long("user-data") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help( "User data for instance initialization systems (such as cloud-init). Must \ be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and / \ characters with padding). Maximum 32 KiB unencoded data.", ), ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) .about("Create an instance") } @@ -4096,20 +4759,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Fetch an instance") } @@ -4119,20 +4782,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Delete an instance") } @@ -4142,32 +4805,31 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -4175,7 +4837,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List an instance's disks") } @@ -4185,26 +4848,40 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("disk") .long("disk") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Attach a disk to an instance") } @@ -4214,26 +4891,40 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("disk") .long("disk") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Detach a disk from an instance") } @@ -4243,26 +4934,40 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("dst-sled-id") .long("dst-sled-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Migrate an instance") } @@ -4272,20 +4977,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Reboot an instance") } @@ -4295,14 +5000,14 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("from-start") .long("from-start") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Character index in the serial buffer from which to read, counting the \ bytes output since instance start. If this is not provided, \ @@ -4313,8 +5018,8 @@ impl Cli { .arg( clap::Arg::new("max-bytes") .long("max-bytes") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Maximum number of bytes of buffered serial console contents to return. \ If the requested range runs to the end of the available buffer, the data \ @@ -4324,8 +5029,8 @@ impl Cli { .arg( clap::Arg::new("most-recent") .long("most-recent") - .required(false) .value_parser(clap::value_parser!(u64)) + .required(false) .help( "Character index in the serial buffer from which to read, counting \ *backward* from the most recently buffered data retrieved from the \ @@ -4335,14 +5040,14 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Fetch an instance's serial console") } @@ -4352,20 +5057,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Stream an instance's serial console") } @@ -4375,20 +5080,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Boot an instance") } @@ -4398,20 +5103,20 @@ impl Cli { .arg( clap::Arg::new("instance") .long("instance") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("project") .long("project") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Stop an instance") } @@ -4421,14 +5126,13 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -4436,7 +5140,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List organizations") } @@ -4446,14 +5151,28 @@ impl Cli { .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create an organization") } @@ -4463,8 +5182,8 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .about("Fetch an organization") } @@ -4474,20 +5193,34 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update an organization") } @@ -4497,8 +5230,8 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .about("Delete an organization") } @@ -4508,8 +5241,8 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .about("Fetch an organization's IAM policy") } @@ -4519,8 +5252,22 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update an organization's IAM policy") } @@ -4530,20 +5277,19 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::NameOrIdSortMode::NameAscending.to_string(), @@ -4551,7 +5297,8 @@ impl Cli { types::NameOrIdSortMode::IdAscending.to_string(), ]), |s| types::NameOrIdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List projects") } @@ -4561,20 +5308,34 @@ impl Cli { .arg( clap::Arg::new("organization") .long("organization") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("description") .long("description") - .required(true) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required_unless_present("json-body"), ) .arg( clap::Arg::new("name") .long("name") - .required(true) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(types::Name)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Create a project") } @@ -4584,14 +5345,14 @@ impl Cli { .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Fetch a project") } @@ -4601,26 +5362,40 @@ impl Cli { .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .arg( clap::Arg::new("description") .long("description") - .required(false) - .value_parser(clap::value_parser!(String)), + .value_parser(clap::value_parser!(String)) + .required(false), ) .arg( clap::Arg::new("name") .long("name") + .value_parser(clap::value_parser!(types::Name)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") .required(false) - .value_parser(clap::value_parser!(types::Name)), + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a project") } @@ -4630,14 +5405,14 @@ impl Cli { .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Delete a project") } @@ -4647,14 +5422,14 @@ impl Cli { .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), ) .about("Fetch a project's IAM policy") } @@ -4664,14 +5439,28 @@ impl Cli { .arg( clap::Arg::new("project") .long("project") - .required(true) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(true), ) .arg( clap::Arg::new("organization") .long("organization") - .required(false) - .value_parser(clap::value_parser!(types::NameOrId)), + .value_parser(clap::value_parser!(types::NameOrId)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Update a project's IAM policy") } @@ -4681,20 +5470,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("View version and update status of component tree") } @@ -4704,20 +5493,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List all update deployments") } @@ -4727,8 +5516,8 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Fetch a system update deployment") } @@ -4742,8 +5531,22 @@ impl Cli { .arg( clap::Arg::new("version") .long("version") - .required(true) - .value_parser(clap::value_parser!(types::SemverVersion)), + .value_parser(clap::value_parser!(types::SemverVersion)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), ) .about("Start system update") } @@ -4759,20 +5562,20 @@ impl Cli { .arg( clap::Arg::new("limit") .long("limit") - .required(false) .value_parser(clap::value_parser!(std::num::NonZeroU32)) + .required(false) .help("Maximum number of items returned by a single call"), ) .arg( clap::Arg::new("sort-by") .long("sort-by") - .required(false) .value_parser(clap::builder::TypedValueParser::map( clap::builder::PossibleValuesParser::new([ types::IdSortMode::IdAscending.to_string() ]), |s| types::IdSortMode::try_from(s).unwrap(), - )), + )) + .required(false), ) .about("List all updates") } @@ -4782,8 +5585,8 @@ impl Cli { .arg( clap::Arg::new("version") .long("version") - .required(true) - .value_parser(clap::value_parser!(types::SemverVersion)), + .value_parser(clap::value_parser!(types::SemverVersion)) + .required(true), ) .about("View system update") } @@ -4793,8 +5596,8 @@ impl Cli { .arg( clap::Arg::new("version") .long("version") - .required(true) - .value_parser(clap::value_parser!(types::SemverVersion)), + .value_parser(clap::value_parser!(types::SemverVersion)) + .required(true), ) .about("View system update component tree") } @@ -5618,6 +6421,12 @@ impl Cli { pub async fn execute_device_auth_request(&self, matches: &clap::ArgMatches) { let mut request = self.client.device_auth_request(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("client-id") { request = request.body_map(|body| body.client_id(value.clone())) } @@ -5638,6 +6447,12 @@ impl Cli { pub async fn execute_device_auth_confirm(&self, matches: &clap::ArgMatches) { let mut request = self.client.device_auth_confirm(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("user-code") { request = request.body_map(|body| body.user_code(value.clone())) } @@ -5658,6 +6473,13 @@ impl Cli { pub async fn execute_device_access_token(&self, matches: &clap::ArgMatches) { let mut request = self.client.device_access_token(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("client-id") { request = request.body_map(|body| body.client_id(value.clone())) } @@ -5714,6 +6536,12 @@ impl Cli { pub async fn execute_login_spoof(&self, matches: &clap::ArgMatches) { let mut request = self.client.login_spoof(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("username") { request = request.body_map(|body| body.username(value.clone())) } @@ -5734,6 +6562,13 @@ impl Cli { pub async fn execute_login_local(&self, matches: &clap::ArgMatches) { let mut request = self.client.login_local(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("silo-name") { request = request.silo_name(value.clone()); } @@ -5852,6 +6687,12 @@ impl Cli { pub async fn execute_organization_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -5896,6 +6737,12 @@ impl Cli { pub async fn execute_organization_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -5964,6 +6811,13 @@ impl Cli { pub async fn execute_organization_policy_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_policy_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6018,6 +6872,12 @@ impl Cli { pub async fn execute_project_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6070,6 +6930,12 @@ impl Cli { pub async fn execute_project_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6162,6 +7028,12 @@ impl Cli { pub async fn execute_disk_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.disk_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6339,6 +7211,12 @@ impl Cli { pub async fn execute_image_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.image_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6463,6 +7341,12 @@ impl Cli { pub async fn execute_instance_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6613,6 +7497,12 @@ impl Cli { pub async fn execute_instance_disk_attach(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_disk_attach(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6645,6 +7535,12 @@ impl Cli { pub async fn execute_instance_disk_detach(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_disk_detach(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6705,6 +7601,12 @@ impl Cli { pub async fn execute_instance_migrate(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_migrate(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6779,6 +7681,13 @@ impl Cli { pub async fn execute_instance_network_interface_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_network_interface_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -6859,6 +7768,13 @@ impl Cli { pub async fn execute_instance_network_interface_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_network_interface_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7111,6 +8027,12 @@ impl Cli { pub async fn execute_project_policy_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_policy_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7173,6 +8095,12 @@ impl Cli { pub async fn execute_snapshot_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.snapshot_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7301,6 +8229,12 @@ impl Cli { pub async fn execute_vpc_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7365,6 +8299,12 @@ impl Cli { pub async fn execute_vpc_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7457,6 +8397,13 @@ impl Cli { pub async fn execute_vpc_firewall_rules_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_firewall_rules_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7527,6 +8474,12 @@ impl Cli { pub async fn execute_vpc_router_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_router_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7595,6 +8548,12 @@ impl Cli { pub async fn execute_vpc_router_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_router_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7713,6 +8672,13 @@ impl Cli { pub async fn execute_vpc_router_route_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_router_route_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7789,6 +8755,13 @@ impl Cli { pub async fn execute_vpc_router_route_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_router_route_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7911,6 +8884,12 @@ impl Cli { pub async fn execute_vpc_subnet_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_subnet_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -7987,6 +8966,12 @@ impl Cli { pub async fn execute_vpc_subnet_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.vpc_subnet_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization-name") { request = request.organization_name(value.clone()); } @@ -8121,6 +9106,12 @@ impl Cli { pub async fn execute_policy_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.policy_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + self.over .execute_policy_update(matches, &mut request) .unwrap(); @@ -8253,6 +9244,12 @@ impl Cli { pub async fn execute_session_sshkey_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.session_sshkey_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -8411,6 +9408,12 @@ impl Cli { pub async fn execute_certificate_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.certificate_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -8665,6 +9668,12 @@ impl Cli { pub async fn execute_system_image_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.system_image_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -8759,6 +9768,12 @@ impl Cli { pub async fn execute_ip_pool_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -8803,6 +9818,12 @@ impl Cli { pub async fn execute_ip_pool_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("pool-name") { request = request.pool_name(value.clone()); } @@ -8881,6 +9902,12 @@ impl Cli { pub async fn execute_ip_pool_range_add(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_range_add(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("pool-name") { request = request.pool_name(value.clone()); } @@ -8901,6 +9928,12 @@ impl Cli { pub async fn execute_ip_pool_range_remove(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_range_remove(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("pool-name") { request = request.pool_name(value.clone()); } @@ -8963,6 +9996,12 @@ impl Cli { pub async fn execute_ip_pool_service_range_add(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_service_range_add(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + self.over .execute_ip_pool_service_range_add(matches, &mut request) .unwrap(); @@ -8979,6 +10018,12 @@ impl Cli { pub async fn execute_ip_pool_service_range_remove(&self, matches: &clap::ArgMatches) { let mut request = self.client.ip_pool_service_range_remove(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + self.over .execute_ip_pool_service_range_remove(matches, &mut request) .unwrap(); @@ -9052,6 +10097,12 @@ impl Cli { pub async fn execute_system_policy_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.system_policy_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + self.over .execute_system_policy_update(matches, &mut request) .unwrap(); @@ -9142,6 +10193,12 @@ impl Cli { pub async fn execute_silo_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.silo_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("admin-group-name") { request = request.body_map(|body| body.admin_group_name(value.clone())) } @@ -9250,6 +10307,12 @@ impl Cli { pub async fn execute_local_idp_user_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.local_idp_user_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("silo-name") { request = request.silo_name(value.clone()); } @@ -9298,6 +10361,12 @@ impl Cli { pub async fn execute_local_idp_user_set_password(&self, matches: &clap::ArgMatches) { let mut request = self.client.local_idp_user_set_password(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("silo-name") { request = request.silo_name(value.clone()); } @@ -9322,6 +10391,13 @@ impl Cli { pub async fn execute_saml_identity_provider_create(&self, matches: &clap::ArgMatches) { let mut request = self.client.saml_identity_provider_create(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("silo-name") { request = request.silo_name(value.clone()); } @@ -9418,6 +10494,12 @@ impl Cli { pub async fn execute_silo_policy_update(&self, matches: &clap::ArgMatches) { let mut request = self.client.silo_policy_update(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("silo-name") { request = request.silo_name(value.clone()); } @@ -9638,6 +10720,12 @@ impl Cli { pub async fn execute_disk_create_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.disk_create_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization") { request = request.organization(value.clone()); } @@ -9768,6 +10856,12 @@ impl Cli { pub async fn execute_instance_create_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_create_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization") { request = request.organization(value.clone()); } @@ -9918,6 +11012,12 @@ impl Cli { pub async fn execute_instance_disk_attach_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_disk_attach_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("instance") { request = request.instance(value.clone()); } @@ -9950,6 +11050,12 @@ impl Cli { pub async fn execute_instance_disk_detach_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_disk_detach_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("instance") { request = request.instance(value.clone()); } @@ -9982,6 +11088,12 @@ impl Cli { pub async fn execute_instance_migrate_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_migrate_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("instance") { request = request.instance(value.clone()); } @@ -10196,6 +11308,12 @@ impl Cli { pub async fn execute_organization_create_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_create_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("description") { request = request.body_map(|body| body.description(value.clone())) } @@ -10240,6 +11358,12 @@ impl Cli { pub async fn execute_organization_update_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_update_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization") { request = request.organization(value.clone()); } @@ -10308,6 +11432,13 @@ impl Cli { pub async fn execute_organization_policy_update_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.organization_policy_update_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization") { request = request.organization(value.clone()); } @@ -10362,6 +11493,12 @@ impl Cli { pub async fn execute_project_create_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_create_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("organization") { request = request.organization(value.clone()); } @@ -10414,6 +11551,12 @@ impl Cli { pub async fn execute_project_update_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_update_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("project") { request = request.project(value.clone()); } @@ -10494,6 +11637,12 @@ impl Cli { pub async fn execute_project_policy_update_v1(&self, matches: &clap::ArgMatches) { let mut request = self.client.project_policy_update_v1(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("project") { request = request.project(value.clone()); } @@ -10614,6 +11763,12 @@ impl Cli { pub async fn execute_system_update_start(&self, matches: &clap::ArgMatches) { let mut request = self.client.system_update_start(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("version") { request = request.body_map(|body| body.version(value.clone())) } diff --git a/progenitor-impl/tests/output/nexus-positional.out b/progenitor-impl/tests/output/nexus-positional.out index 67db633..68818d4 100644 --- a/progenitor-impl/tests/output/nexus-positional.out +++ b/progenitor-impl/tests/output/nexus-positional.out @@ -6481,7 +6481,7 @@ impl Client { self.group_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -6489,10 +6489,7 @@ impl Client { self.group_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -6738,7 +6735,7 @@ impl Client { self.organization_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -6746,10 +6743,7 @@ impl Client { self.organization_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -7085,7 +7079,7 @@ impl Client { self.project_list(organization_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -7093,10 +7087,7 @@ impl Client { self.project_list(organization_name, None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -7378,7 +7369,7 @@ impl Client { self.disk_list(organization_name, project_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -7392,10 +7383,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -7654,7 +7642,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -7671,10 +7659,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -7784,7 +7769,7 @@ impl Client { self.image_list(organization_name, project_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -7798,10 +7783,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -8038,7 +8020,7 @@ impl Client { self.instance_list(organization_name, project_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -8052,10 +8034,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -8304,7 +8283,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -8319,10 +8298,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -8612,7 +8588,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -8627,10 +8603,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -9241,7 +9214,7 @@ impl Client { self.snapshot_list(organization_name, project_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -9255,10 +9228,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -9488,7 +9458,7 @@ impl Client { self.vpc_list(organization_name, project_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -9502,10 +9472,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -9871,7 +9838,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -9886,10 +9853,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -10188,7 +10152,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -10204,10 +10168,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -10503,7 +10464,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -10518,10 +10479,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -10816,7 +10774,7 @@ impl Client { ) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -10832,10 +10790,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -10976,7 +10931,7 @@ impl Client { self.role_list(limit, None) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -10984,10 +10939,7 @@ impl Client { self.role_list(None, state.as_deref()) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -11142,7 +11094,7 @@ impl Client { self.session_me_groups(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -11150,10 +11102,7 @@ impl Client { self.session_me_groups(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -11246,7 +11195,7 @@ impl Client { self.session_sshkey_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -11254,10 +11203,7 @@ impl Client { self.session_sshkey_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -11564,7 +11510,7 @@ impl Client { self.certificate_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -11572,10 +11518,7 @@ impl Client { self.certificate_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -11771,7 +11714,7 @@ impl Client { self.physical_disk_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -11779,10 +11722,7 @@ impl Client { self.physical_disk_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -11871,7 +11811,7 @@ impl Client { self.rack_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -11879,10 +11819,7 @@ impl Client { self.rack_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12008,7 +11945,7 @@ impl Client { self.sled_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12016,10 +11953,7 @@ impl Client { self.sled_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12155,7 +12089,7 @@ impl Client { self.sled_physical_disk_list(sled_id, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12163,10 +12097,7 @@ impl Client { self.sled_physical_disk_list(sled_id, None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12264,7 +12195,7 @@ impl Client { self.system_image_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12272,10 +12203,7 @@ impl Client { self.system_image_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12472,7 +12400,7 @@ impl Client { self.ip_pool_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12480,10 +12408,7 @@ impl Client { self.ip_pool_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12712,7 +12637,7 @@ impl Client { self.ip_pool_range_list(pool_name, limit, None) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12720,10 +12645,7 @@ impl Client { self.ip_pool_range_list(pool_name, None, state.as_deref()) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -12910,7 +12832,7 @@ impl Client { self.ip_pool_service_range_list(limit, None) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -12918,10 +12840,7 @@ impl Client { self.ip_pool_service_range_list(None, state.as_deref()) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -13199,7 +13118,7 @@ impl Client { self.saga_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -13207,10 +13126,7 @@ impl Client { self.saga_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -13337,7 +13253,7 @@ impl Client { self.silo_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -13345,10 +13261,7 @@ impl Client { self.silo_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -13556,7 +13469,7 @@ impl Client { self.silo_identity_provider_list(silo_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -13564,10 +13477,7 @@ impl Client { self.silo_identity_provider_list(silo_name, None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -13957,7 +13867,7 @@ impl Client { self.silo_users_list(silo_name, limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -13965,10 +13875,7 @@ impl Client { self.silo_users_list(silo_name, None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14098,7 +14005,7 @@ impl Client { self.system_user_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14106,10 +14013,7 @@ impl Client { self.system_user_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14228,7 +14132,7 @@ impl Client { self.timeseries_schema_get(limit, None) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14236,10 +14140,7 @@ impl Client { self.timeseries_schema_get(None, state.as_deref()) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14328,7 +14229,7 @@ impl Client { self.user_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14336,10 +14237,7 @@ impl Client { self.user_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14444,7 +14342,7 @@ impl Client { self.disk_list_v1(limit, organization, None, project, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14452,10 +14350,7 @@ impl Client { self.disk_list_v1(None, None, state.as_deref(), None, None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14693,7 +14588,7 @@ impl Client { self.instance_list_v1(limit, organization, None, project, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14701,10 +14596,7 @@ impl Client { self.instance_list_v1(None, None, state.as_deref(), None, None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -14949,7 +14841,7 @@ impl Client { self.instance_disk_list_v1(instance, limit, organization, None, project, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -14964,10 +14856,7 @@ impl Client { ) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -15464,7 +15353,7 @@ impl Client { self.organization_list_v1(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -15472,10 +15361,7 @@ impl Client { self.organization_list_v1(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -15777,7 +15663,7 @@ impl Client { self.project_list_v1(limit, organization, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -15785,10 +15671,7 @@ impl Client { self.project_list_v1(None, None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -16122,7 +16005,7 @@ impl Client { self.system_component_version_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -16130,10 +16013,7 @@ impl Client { self.system_component_version_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -16223,7 +16103,7 @@ impl Client { self.update_deployments_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -16231,10 +16111,7 @@ impl Client { self.update_deployments_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } @@ -16449,7 +16326,7 @@ impl Client { self.system_update_list(limit, None, sort_by) .map_ok(move |page| { let page = page.into_inner(); - let first = futures::stream::iter(page.items.into_iter().map(Ok)); + let first = futures::stream::iter(page.items).map(Ok); let rest = futures::stream::try_unfold(page.next_page, move |state| async move { if state.is_none() { Ok(None) @@ -16457,10 +16334,7 @@ impl Client { self.system_update_list(None, state.as_deref(), None) .map_ok(|page| { let page = page.into_inner(); - Some(( - futures::stream::iter(page.items.into_iter().map(Ok)), - page.next_page, - )) + Some((futures::stream::iter(page.items).map(Ok), page.next_page)) }) .await } diff --git a/progenitor-impl/tests/output/param-overrides-cli.out b/progenitor-impl/tests/output/param-overrides-cli.out index 30839ee..5bd01a4 100644 --- a/progenitor-impl/tests/output/param-overrides-cli.out +++ b/progenitor-impl/tests/output/param-overrides-cli.out @@ -19,15 +19,15 @@ impl Cli { .arg( clap::Arg::new("key") .long("key") - .required(false) .value_parser(clap::value_parser!(bool)) + .required(false) .help("The same key parameter that overlaps with the path level parameter"), ) .arg( clap::Arg::new("unique-key") .long("unique-key") - .required(false) .value_parser(clap::value_parser!(String)) + .required(false) .help("A key parameter that will not be overridden by the path spec"), ) .long_about("Gets a key") diff --git a/progenitor-impl/tests/output/propolis-server-cli.out b/progenitor-impl/tests/output/propolis-server-cli.out index 1fa6022..7d42f70 100644 --- a/progenitor-impl/tests/output/propolis-server-cli.out +++ b/progenitor-impl/tests/output/propolis-server-cli.out @@ -27,12 +27,27 @@ impl Cli { } pub fn cli_instance_ensure() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("cloud-init-bytes") - .long("cloud-init-bytes") - .required(false) - .value_parser(clap::value_parser!(String)), - ) + clap::Command::new("") + .arg( + clap::Arg::new("cloud-init-bytes") + .long("cloud-init-bytes") + .value_parser(clap::value_parser!(String)) + .required(false), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(true) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_instance_issue_crucible_snapshot_request() -> clap::Command { @@ -40,25 +55,40 @@ impl Cli { .arg( clap::Arg::new("id") .long("id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .arg( clap::Arg::new("snapshot-id") .long("snapshot-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), + .value_parser(clap::value_parser!(uuid::Uuid)) + .required(true), ) .about("Issue a snapshot request to a crucible backend") } pub fn cli_instance_migrate_status() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("migration-id") - .long("migration-id") - .required(true) - .value_parser(clap::value_parser!(uuid::Uuid)), - ) + clap::Command::new("") + .arg( + clap::Arg::new("migration-id") + .long("migration-id") + .value_parser(clap::value_parser!(uuid::Uuid)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_instance_serial() -> clap::Command { @@ -67,15 +97,44 @@ impl Cli { pub fn cli_instance_state_put() -> clap::Command { clap::Command::new("") + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } pub fn cli_instance_state_monitor() -> clap::Command { - clap::Command::new("").arg( - clap::Arg::new("gen") - .long("gen") - .required(true) - .value_parser(clap::value_parser!(u64)), - ) + clap::Command::new("") + .arg( + clap::Arg::new("gen") + .long("gen") + .value_parser(clap::value_parser!(u64)) + .required_unless_present("json-body"), + ) + .arg( + clap::Arg::new("json-body") + .long("json-body") + .value_name("JSON-FILE") + .required(false) + .value_parser(clap::value_parser!(std::path::PathBuf)) + .help("Path to a file that contains the full json body."), + ) + .arg( + clap::Arg::new("json-body-template") + .long("json-body-template") + .action(clap::ArgAction::SetTrue) + .help("XXX"), + ) } } @@ -129,6 +188,13 @@ impl Cli { pub async fn execute_instance_ensure(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_ensure(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("cloud-init-bytes") { request = request.body_map(|body| body.cloud_init_bytes(value.clone())) } @@ -176,6 +242,13 @@ impl Cli { pub async fn execute_instance_migrate_status(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_migrate_status(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("migration-id") { request = request.body_map(|body| body.migration_id(value.clone())) } @@ -212,6 +285,13 @@ impl Cli { pub async fn execute_instance_state_put(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_state_put(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + self.over .execute_instance_state_put(matches, &mut request) .unwrap(); @@ -228,6 +308,13 @@ impl Cli { pub async fn execute_instance_state_monitor(&self, matches: &clap::ArgMatches) { let mut request = self.client.instance_state_monitor(); + if let Some(value) = matches.get_one::("json-body") { + let body_txt = std::fs::read_to_string(value).unwrap(); + let body_value = + serde_json::from_str::(&body_txt).unwrap(); + request = request.body(body_value); + } + if let Some(value) = matches.get_one::("gen") { request = request.body_map(|body| body.gen(value.clone())) }