CLI: generate a fixed list of valid values for enum types (#442)

This commit is contained in:
Adam Leventhal 2023-04-26 15:15:07 -07:00 committed by GitHub
parent b2e1eee042
commit 6a515c304f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 376 additions and 100 deletions

View File

@ -4,7 +4,7 @@ use heck::ToKebabCase;
use openapiv3::OpenAPI; use openapiv3::OpenAPI;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use typify::{TypeSpaceImpl, TypeStructPropInfo}; use typify::{Type, TypeEnumVariant, TypeSpaceImpl, TypeStructPropInfo};
use crate::{ use crate::{
method::{ method::{
@ -247,7 +247,6 @@ impl Generator {
prop_type prop_type
}; };
let prop_type_ident = prop_type.ident();
let scalar = let scalar =
prop_type.has_impl(TypeSpaceImpl::FromStr); prop_type.has_impl(TypeSpaceImpl::FromStr);
let prop_name = prop_name.to_kebab_case(); let prop_name = prop_name.to_kebab_case();
@ -266,7 +265,7 @@ impl Generator {
prop_name.clone(), prop_name.clone(),
required, required,
description.map(str::to_string), description.map(str::to_string),
prop_type_ident.clone(), prop_type,
) )
}) })
}) })
@ -296,52 +295,34 @@ impl Generator {
OperationParameterKind::Body(_) => unreachable!(), OperationParameterKind::Body(_) => unreachable!(),
}; };
let OperationParameterType::Type(arg_type_id) = &param.typ else { let OperationParameterType::Type(arg_type_id) = &param.typ
else {
panic!() panic!()
}; };
let arg_type = self.type_space.get_type(arg_type_id).unwrap(); let arg_type = self.type_space.get_type(arg_type_id).unwrap();
let arg_details = arg_type.details();
let arg_type_name = match &arg_details{ let maybe_inner_type =
typify::TypeDetails::Option(opt_id) => { if let typify::TypeDetails::Option(inner_type_id) =
let inner_type = self.type_space.get_type(opt_id).unwrap(); arg_type.details()
inner_type.ident() {
} let inner_type =
_ => { self.type_space.get_type(&inner_type_id).unwrap();
arg_type.ident() Some(inner_type)
} } else {
None
};
let arg_type = if let Some(inner_type) = maybe_inner_type {
inner_type
} else {
arg_type
}; };
let help = param.description.as_ref().map(|description| { clap_arg(&arg_name, required, &param.description, &arg_type)
quote! {
.help(#description)
}
});
quote! {
clap::Arg::new(#arg_name)
.long(#arg_name)
.required(#required)
.value_parser(clap::value_parser!(#arg_type_name))
#help
}
}); });
let body_args = body_params.iter().map( let body_args = body_params.iter().map(
|(prop_name, required, description, prop_type_ident)| { |(prop_name, required, description, prop_type)| {
let help = description.as_ref().map(|description| { clap_arg(prop_name, *required, description, prop_type)
quote! {
.help(#description)
}
});
quote! {
clap::Arg::new(#prop_name)
.long(#prop_name)
.required(#required)
.value_parser(clap::value_parser!(
#prop_type_ident
))
#help
}
}, },
); );
@ -421,11 +402,10 @@ impl Generator {
// Build up the iterator processing each body property we can handle. // Build up the iterator processing each body property we can handle.
let body_args = let body_args =
body_params body_params.iter().map(|(prop_name, _, _, prop_type)| {
.iter()
.map(|(prop_name, _, _, prop_type_ident)| {
let prop_fn = let prop_fn =
format_ident!("{}", sanitize(prop_name, Case::Snake)); format_ident!("{}", sanitize(prop_name, Case::Snake));
let prop_type_ident = prop_type.ident();
quote! { quote! {
if let Some(value) = if let Some(value) =
matches.get_one::<#prop_type_ident>( matches.get_one::<#prop_type_ident>(
@ -520,3 +500,68 @@ impl Generator {
} }
} }
} }
fn clap_arg(
arg_name: &str,
required: bool,
description: &Option<String>,
arg_type: &Type,
) -> TokenStream {
let help = description.as_ref().map(|description| {
quote! {
.help(#description)
}
});
let arg_type_name = arg_type.ident();
// For enums that have **only** simple variants, we do some slightly
// fancier argument handling to expose the possible values. In particular,
// we use clap's `PossibleValuesParser` with each variant converted to a
// string. Then we use TypedValueParser::map to translate that into the
// actual type of the enum.
let maybe_enum_parser =
if let typify::TypeDetails::Enum(e) = arg_type.details() {
let maybe_var_names = e
.variants()
.map(|(var_name, var_details)| {
if let TypeEnumVariant::Simple = var_details {
Some(format_ident!("{}", var_name))
} else {
None
}
})
.collect::<Option<Vec<_>>>();
maybe_var_names.map(|var_names| {
quote! {
clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
#( #arg_type_name :: #var_names.to_string(), )*
]),
|s| #arg_type_name :: try_from(s).unwrap()
)
}
})
} else {
None
};
let value_parser = if let Some(enum_parser) = maybe_enum_parser {
enum_parser
} else {
// Let clap pick a value parser for us. This has the benefit of
// allowing for override implementations. A generated client may
// implement ValueParserFactory for a type to create a custom parser.
quote! {
clap::value_parser!(#arg_type_name)
}
};
quote! {
clap::Arg::new(#arg_name)
.long(#arg_name)
.required(#required)
.value_parser(#value_parser)
#help
}
}

View File

@ -411,7 +411,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List groups") .about("List groups")
} }
@ -502,7 +507,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List organizations\n\nUse `GET /v1/organizations` instead") .about("List organizations\n\nUse `GET /v1/organizations` instead")
} }
@ -624,7 +636,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List projects\n\nUse `GET /v1/projects` instead") .about("List projects\n\nUse `GET /v1/projects` instead")
} }
@ -749,7 +768,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List disks\n\nUse `GET /v1/disks` instead") .about("List disks\n\nUse `GET /v1/disks` instead")
} }
@ -862,7 +886,17 @@ impl Cli {
clap::Arg::new("metric-name") clap::Arg::new("metric-name")
.long("metric-name") .long("metric-name")
.required(true) .required(true)
.value_parser(clap::value_parser!(types::DiskMetricName)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::DiskMetricName::Activated.to_string(),
types::DiskMetricName::Flush.to_string(),
types::DiskMetricName::Read.to_string(),
types::DiskMetricName::ReadBytes.to_string(),
types::DiskMetricName::Write.to_string(),
types::DiskMetricName::WriteBytes.to_string(),
]),
|s| types::DiskMetricName::try_from(s).unwrap(),
)),
) )
.arg( .arg(
clap::Arg::new("end-time") clap::Arg::new("end-time")
@ -915,7 +949,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about( .about(
"List images\n\nList images in a project. The images are returned sorted by \ "List images\n\nList images in a project. The images are returned sorted by \
@ -1031,7 +1070,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List instances") .about("List instances")
} }
@ -1180,7 +1224,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List an instance's disks\n\nUse `GET /v1/instances/{instance}/disks` instead") .about("List an instance's disks\n\nUse `GET /v1/instances/{instance}/disks` instead")
} }
@ -1329,7 +1378,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List network interfaces") .about("List network interfaces")
} }
@ -1735,7 +1789,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List snapshots") .about("List snapshots")
} }
@ -1851,7 +1910,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List VPCs") .about("List VPCs")
} }
@ -2069,7 +2133,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List routers") .about("List routers")
} }
@ -2245,7 +2314,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List routes\n\nList the routes associated with a router in a particular VPC.") .about("List routes\n\nList the routes associated with a router in a particular VPC.")
} }
@ -2439,7 +2513,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List subnets") .about("List subnets")
} }
@ -2638,7 +2717,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List network interfaces") .about("List network interfaces")
} }
@ -2692,7 +2776,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("Fetch the silo\u{a0}groups the current user belongs to") .about("Fetch the silo\u{a0}groups the current user belongs to")
} }
@ -2710,7 +2799,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about( .about(
"List SSH public keys\n\nLists SSH public keys for the currently authenticated \ "List SSH public keys\n\nLists SSH public keys for the currently authenticated \
@ -2819,7 +2913,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about( .about(
"List system-wide certificates\n\nReturns a list of all the system-wide \ "List system-wide certificates\n\nReturns a list of all the system-wide \
@ -2846,7 +2945,12 @@ impl Cli {
clap::Arg::new("service") clap::Arg::new("service")
.long("service") .long("service")
.required(true) .required(true)
.value_parser(clap::value_parser!(types::ServiceUsingCertificate)) .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::ServiceUsingCertificate::ExternalApi.to_string(),
]),
|s| types::ServiceUsingCertificate::try_from(s).unwrap(),
))
.help("The service using this certificate"), .help("The service using this certificate"),
) )
.about( .about(
@ -2893,7 +2997,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List physical disks") .about("List physical disks")
} }
@ -2911,7 +3020,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List racks") .about("List racks")
} }
@ -2941,7 +3055,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List sleds") .about("List sleds")
} }
@ -2978,7 +3097,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List physical disks attached to sleds") .about("List physical disks attached to sleds")
} }
@ -2996,7 +3120,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about( .about(
"List system-wide images\n\nReturns a list of all the system-wide images. \ "List system-wide images\n\nReturns a list of all the system-wide images. \
@ -3066,7 +3195,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List IP pools") .about("List IP pools")
} }
@ -3206,7 +3342,14 @@ impl Cli {
clap::Arg::new("metric-name") clap::Arg::new("metric-name")
.long("metric-name") .long("metric-name")
.required(true) .required(true)
.value_parser(clap::value_parser!(types::SystemMetricName)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::SystemMetricName::VirtualDiskSpaceProvisioned.to_string(),
types::SystemMetricName::CpusProvisioned.to_string(),
types::SystemMetricName::RamProvisioned.to_string(),
]),
|s| types::SystemMetricName::try_from(s).unwrap(),
)),
) )
.arg( .arg(
clap::Arg::new("end-time") clap::Arg::new("end-time")
@ -3267,7 +3410,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List sagas") .about("List sagas")
} }
@ -3296,7 +3444,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about( .about(
"List silos\n\nLists silos that are discoverable based on the current permissions.", "List silos\n\nLists silos that are discoverable based on the current permissions.",
@ -3335,7 +3490,13 @@ impl Cli {
clap::Arg::new("identity-mode") clap::Arg::new("identity-mode")
.long("identity-mode") .long("identity-mode")
.required(true) .required(true)
.value_parser(clap::value_parser!(types::SiloIdentityMode)), .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(),
)),
) )
.arg( .arg(
clap::Arg::new("name") clap::Arg::new("name")
@ -3390,7 +3551,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List a silo's IDPs") .about("List a silo's IDPs")
} }
@ -3592,7 +3758,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List users in a silo") .about("List users in a silo")
} }
@ -3629,7 +3800,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameSortMode::NameAscending.to_string(),
]),
|s| types::NameSortMode::try_from(s).unwrap(),
)),
) )
.about("List built-in users") .about("List built-in users")
} }
@ -3671,7 +3847,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List users") .about("List users")
} }
@ -3701,7 +3882,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List disks") .about("List disks")
} }
@ -3813,7 +4001,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List instances") .about("List instances")
} }
@ -3960,7 +4155,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List an instance's disks") .about("List an instance's disks")
} }
@ -4214,7 +4416,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List organizations") .about("List organizations")
} }
@ -4322,7 +4531,14 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::NameOrIdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::NameOrIdSortMode::NameAscending.to_string(),
types::NameOrIdSortMode::NameDescending.to_string(),
types::NameOrIdSortMode::IdAscending.to_string(),
]),
|s| types::NameOrIdSortMode::try_from(s).unwrap(),
)),
) )
.about("List projects") .about("List projects")
} }
@ -4460,7 +4676,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("View version and update status of component tree") .about("View version and update status of component tree")
} }
@ -4478,7 +4699,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List all update deployments") .about("List all update deployments")
} }
@ -4527,7 +4753,12 @@ impl Cli {
clap::Arg::new("sort-by") clap::Arg::new("sort-by")
.long("sort-by") .long("sort-by")
.required(false) .required(false)
.value_parser(clap::value_parser!(types::IdSortMode)), .value_parser(clap::builder::TypedValueParser::map(
clap::builder::PossibleValuesParser::new([
types::IdSortMode::IdAscending.to_string()
]),
|s| types::IdSortMode::try_from(s).unwrap(),
)),
) )
.about("List all updates") .about("List all updates")
} }