CLI: add an output interface for consumers (#708)

This commit is contained in:
Adam Leventhal 2024-02-05 15:01:38 -08:00 committed by GitHub
parent fa0e6c7976
commit dc5e1f1840
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 2669 additions and 2383 deletions

View File

@ -102,19 +102,22 @@ impl Generator {
let crate_path = syn::TypePath {
qself: None,
path: syn::parse_str(&crate_name).unwrap(),
path: syn::parse_str(crate_name).unwrap(),
};
let code = quote! {
use #crate_path::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(
client: Client,
config: T,
) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -126,26 +129,17 @@ impl Generator {
}
#(#cli_ops)*
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(
client: Client,
over: T,
) -> Self {
Self { client, over }
}
pub async fn execute(
&self,
cmd: CliCommand,
matches: &clap::ArgMatches,
) {
) -> anyhow::Result<()> {
match cmd {
#(
CliCommand::#cli_variants => {
// TODO ... do something with output
self.#execute_fns(matches).await;
self.#execute_fns(matches).await
}
)*
}
@ -154,12 +148,30 @@ impl Generator {
#(#execute_ops)*
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
#(#trait_ops)*
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
#(#cli_variants,)*
@ -216,67 +228,111 @@ impl Generator {
let fn_name = format_ident!("execute_{}", &method.operation_id);
let op_name = format_ident!("{}", &method.operation_id);
let (_, success_type) = self.extract_responses(
let (_, success_kind) = self.extract_responses(
method,
OperationResponseStatus::is_success_or_default,
);
let (_, error_type) = self.extract_responses(
let (_, error_kind) = self.extract_responses(
method,
OperationResponseStatus::is_error_or_default,
);
let success_output = match success_type {
crate::method::OperationResponseType::Type(_) => {
quote! { println!("success\n{:#?}", r) }
}
crate::method::OperationResponseType::None => {
quote! { println!("success\n{:#?}", r) }
}
crate::method::OperationResponseType::Raw => quote! { todo!() },
crate::method::OperationResponseType::Upgrade => quote! { todo!() },
};
let error_output = match error_type {
crate::method::OperationResponseType::Type(_) => {
quote! { println!("error\n{:#?}", r) }
}
crate::method::OperationResponseType::None => {
quote! { println!("success\n{:#?}", r) }
}
crate::method::OperationResponseType::Raw => quote! { todo!() },
crate::method::OperationResponseType::Upgrade => quote! { todo!() },
};
let execute_and_output = match method.dropshot_paginated {
// Normal, one-shot API calls.
None => {
let success_output = match success_kind {
crate::method::OperationResponseKind::Type(_)
| crate::method::OperationResponseKind::None => {
quote! {
{
self.config.item_success(&r);
Ok(())
}
}
}
crate::method::OperationResponseKind::Raw
| crate::method::OperationResponseKind::Upgrade => {
quote! {
{
todo!()
}
}
}
};
let error_output = match error_kind {
crate::method::OperationResponseKind::Type(_)
| crate::method::OperationResponseKind::None => {
quote! {
{
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
crate::method::OperationResponseKind::Raw
| crate::method::OperationResponseKind::Upgrade => {
quote! {
{
todo!()
}
}
}
};
quote! {
let result = request.send().await;
match result {
Ok(r) => {
#success_output
}
Err(r) => {
#error_output
}
Ok(r) => #success_output
Err(r) => #error_output
}
}
}
// Paginated APIs for which we iterate over each item.
Some(_) => {
let success_type = match success_kind {
crate::method::OperationResponseKind::Type(type_id) => {
self.type_space.get_type(&type_id).unwrap().ident()
}
crate::method::OperationResponseKind::None => quote! { () },
crate::method::OperationResponseKind::Raw => todo!(),
crate::method::OperationResponseKind::Upgrade => todo!(),
};
let error_output = match error_kind {
crate::method::OperationResponseKind::Type(_)
| crate::method::OperationResponseKind::None => {
quote! {
{
self.config.list_end_error(&r);
return Err(anyhow::Error::new(r))
}
}
}
crate::method::OperationResponseKind::Raw
| crate::method::OperationResponseKind::Upgrade => {
quote! {
{
todo!()
}
}
}
};
quote! {
self.config.list_start::<#success_type>();
let mut stream = request.stream();
loop {
match futures::TryStreamExt::try_next(&mut stream).await {
Err(r) => {
#error_output;
break;
}
Err(r) => #error_output
Ok(None) => {
break;
self.config.list_end_success::<#success_type>();
return Ok(());
}
Ok(Some(value)) => {
println!("{:#?}", value);
self.config.list_item(&value);
}
}
}
@ -286,17 +342,13 @@ impl Generator {
let execute_fn = quote! {
pub async fn #fn_name(&self, matches: &clap::ArgMatches)
// ->
// Result<ResponseValue<#success_type>, Error<#error_type>>
-> anyhow::Result<()>
{
let mut request = self.client.#op_name();
#consumer_args
// Call the override function.
// TODO don't want to unwrap.
self.over
.#fn_name(matches, &mut request)
.unwrap();
self.config.#fn_name(matches, &mut request)?;
#execute_and_output
}
@ -311,7 +363,7 @@ impl Generator {
&self,
matches: &clap::ArgMatches,
request: &mut builder :: #struct_ident,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
};

View File

@ -81,7 +81,7 @@ impl Generator {
let crate_path = syn::TypePath {
qself: None,
path: syn::parse_str(&crate_name).unwrap(),
path: syn::parse_str(crate_name).unwrap(),
};
let code = quote! {
@ -295,7 +295,7 @@ impl Generator {
status_code, typ, ..
}| {
let (value_param, value_use) = match typ {
crate::method::OperationResponseType::Type(arg_type_id) => {
crate::method::OperationResponseKind::Type(arg_type_id) => {
let arg_type =
self.type_space.get_type(arg_type_id).unwrap();
let arg_type_ident = arg_type.parameter_ident();
@ -309,10 +309,10 @@ impl Generator {
},
)
}
crate::method::OperationResponseType::None => {
crate::method::OperationResponseKind::None => {
Default::default()
}
crate::method::OperationResponseType::Raw => (
crate::method::OperationResponseKind::Raw => (
quote! {
value: serde_json::Value,
},
@ -321,7 +321,7 @@ impl Generator {
.json_body(value)
},
),
crate::method::OperationResponseType::Upgrade => {
crate::method::OperationResponseKind::Upgrade => {
Default::default()
}
};

View File

@ -166,7 +166,7 @@ impl std::fmt::Display for BodyContentType {
Self::OctetStream => "application/octet-stream",
Self::Json => "application/json",
Self::FormUrlencoded => "application/x-www-form-urlencoded",
Self::Text(typ) => &typ,
Self::Text(typ) => typ,
})
}
}
@ -174,7 +174,7 @@ impl std::fmt::Display for BodyContentType {
#[derive(Debug)]
pub(crate) struct OperationResponse {
pub status_code: OperationResponseStatus,
pub typ: OperationResponseType,
pub typ: OperationResponseKind,
// TODO this isn't currently used because dropshot doesn't give us a
// particularly useful message here.
#[allow(dead_code)]
@ -257,27 +257,27 @@ impl PartialOrd for OperationResponseStatus {
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub(crate) enum OperationResponseType {
pub(crate) enum OperationResponseKind {
Type(TypeId),
None,
Raw,
Upgrade,
}
impl OperationResponseType {
impl OperationResponseKind {
pub fn into_tokens(self, type_space: &TypeSpace) -> TokenStream {
match self {
OperationResponseType::Type(ref type_id) => {
OperationResponseKind::Type(ref type_id) => {
let type_name = type_space.get_type(type_id).unwrap().ident();
quote! { #type_name }
}
OperationResponseType::None => {
OperationResponseKind::None => {
quote! { () }
}
OperationResponseType::Raw => {
OperationResponseKind::Raw => {
quote! { ByteStream }
}
OperationResponseType::Upgrade => {
OperationResponseKind::Upgrade => {
quote! { reqwest::Upgraded }
}
}
@ -508,13 +508,13 @@ impl Generator {
todo!("media type encoding, no schema: {:#?}", mt);
};
OperationResponseType::Type(typ)
OperationResponseKind::Type(typ)
} else if dropshot_websocket {
OperationResponseType::Upgrade
OperationResponseKind::Upgrade
} else if response.content.first().is_some() {
OperationResponseType::Raw
OperationResponseKind::Raw
} else {
OperationResponseType::None
OperationResponseKind::None
};
// See if there's a status code that covers success cases.
@ -548,7 +548,7 @@ impl Generator {
if !success {
responses.push(OperationResponse {
status_code: OperationResponseStatus::Range(2),
typ: OperationResponseType::Raw,
typ: OperationResponseKind::Raw,
description: None,
});
}
@ -557,7 +557,7 @@ impl Generator {
if dropshot_websocket {
responses.push(OperationResponse {
status_code: OperationResponseStatus::Code(101),
typ: OperationResponseType::Upgrade,
typ: OperationResponseKind::Upgrade,
description: None,
})
}
@ -1019,22 +1019,22 @@ impl Generator {
};
let decode = match &response.typ {
OperationResponseType::Type(_) => {
OperationResponseKind::Type(_) => {
quote! {
ResponseValue::from_response(#response_ident).await
}
}
OperationResponseType::None => {
OperationResponseKind::None => {
quote! {
Ok(ResponseValue::empty(#response_ident))
}
}
OperationResponseType::Raw => {
OperationResponseKind::Raw => {
quote! {
Ok(ResponseValue::stream(#response_ident))
}
}
OperationResponseType::Upgrade => {
OperationResponseKind::Upgrade => {
quote! {
ResponseValue::upgrade(#response_ident).await
}
@ -1068,7 +1068,7 @@ impl Generator {
};
let decode = match &response.typ {
OperationResponseType::Type(_) => {
OperationResponseKind::Type(_) => {
quote! {
Err(Error::ErrorResponse(
ResponseValue::from_response(#response_ident)
@ -1076,21 +1076,21 @@ impl Generator {
))
}
}
OperationResponseType::None => {
OperationResponseKind::None => {
quote! {
Err(Error::ErrorResponse(
ResponseValue::empty(#response_ident)
))
}
}
OperationResponseType::Raw => {
OperationResponseKind::Raw => {
quote! {
Err(Error::ErrorResponse(
ResponseValue::stream(#response_ident)
))
}
}
OperationResponseType::Upgrade => {
OperationResponseKind::Upgrade => {
if response.status_code
== OperationResponseStatus::Default
{
@ -1109,8 +1109,8 @@ impl Generator {
let accept_header = matches!(
(&response_type, &error_type),
(OperationResponseType::Type(_), _)
| (OperationResponseType::None, OperationResponseType::Type(_))
(OperationResponseKind::Type(_), _)
| (OperationResponseKind::None, OperationResponseKind::Type(_))
)
.then(|| {
quote! {
@ -1233,7 +1233,7 @@ impl Generator {
&self,
method: &'a OperationMethod,
filter: fn(&OperationResponseStatus) -> bool,
) -> (Vec<&'a OperationResponse>, OperationResponseType) {
) -> (Vec<&'a OperationResponse>, OperationResponseKind) {
let mut response_items = method
.responses
.iter()
@ -1273,7 +1273,7 @@ impl Generator {
.into_iter()
.next()
// TODO should this be OperationResponseType::Raw?
.unwrap_or(OperationResponseType::None);
.unwrap_or(OperationResponseKind::None);
(response_items, response_type)
}
@ -1333,7 +1333,7 @@ impl Generator {
(
OperationResponseStatus::Code(200..=299)
| OperationResponseStatus::Range(2),
OperationResponseType::Type(type_id),
OperationResponseKind::Type(type_id),
) => Some(type_id),
_ => None,
}

View File

@ -1,12 +1,12 @@
use crate::buildomat_builder::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(client: Client, config: T) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -315,140 +315,102 @@ impl Cli {
pub fn cli_workers_recycle() -> clap::Command {
clap::Command::new("")
}
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(client: Client, over: T) -> Self {
Self { client, over }
}
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) {
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) -> anyhow::Result<()> {
match cmd {
CliCommand::ControlHold => {
self.execute_control_hold(matches).await;
}
CliCommand::ControlResume => {
self.execute_control_resume(matches).await;
}
CliCommand::TaskGet => {
self.execute_task_get(matches).await;
}
CliCommand::TasksGet => {
self.execute_tasks_get(matches).await;
}
CliCommand::TaskSubmit => {
self.execute_task_submit(matches).await;
}
CliCommand::TaskEventsGet => {
self.execute_task_events_get(matches).await;
}
CliCommand::TaskOutputsGet => {
self.execute_task_outputs_get(matches).await;
}
CliCommand::TaskOutputDownload => {
self.execute_task_output_download(matches).await;
}
CliCommand::UserCreate => {
self.execute_user_create(matches).await;
}
CliCommand::Whoami => {
self.execute_whoami(matches).await;
}
CliCommand::WhoamiPutName => {
self.execute_whoami_put_name(matches).await;
}
CliCommand::WorkerBootstrap => {
self.execute_worker_bootstrap(matches).await;
}
CliCommand::WorkerPing => {
self.execute_worker_ping(matches).await;
}
CliCommand::WorkerTaskAppend => {
self.execute_worker_task_append(matches).await;
}
CliCommand::ControlHold => self.execute_control_hold(matches).await,
CliCommand::ControlResume => self.execute_control_resume(matches).await,
CliCommand::TaskGet => self.execute_task_get(matches).await,
CliCommand::TasksGet => self.execute_tasks_get(matches).await,
CliCommand::TaskSubmit => self.execute_task_submit(matches).await,
CliCommand::TaskEventsGet => self.execute_task_events_get(matches).await,
CliCommand::TaskOutputsGet => self.execute_task_outputs_get(matches).await,
CliCommand::TaskOutputDownload => self.execute_task_output_download(matches).await,
CliCommand::UserCreate => self.execute_user_create(matches).await,
CliCommand::Whoami => self.execute_whoami(matches).await,
CliCommand::WhoamiPutName => self.execute_whoami_put_name(matches).await,
CliCommand::WorkerBootstrap => self.execute_worker_bootstrap(matches).await,
CliCommand::WorkerPing => self.execute_worker_ping(matches).await,
CliCommand::WorkerTaskAppend => self.execute_worker_task_append(matches).await,
CliCommand::WorkerTaskUploadChunk => {
self.execute_worker_task_upload_chunk(matches).await;
}
CliCommand::WorkerTaskComplete => {
self.execute_worker_task_complete(matches).await;
}
CliCommand::WorkerTaskAddOutput => {
self.execute_worker_task_add_output(matches).await;
}
CliCommand::WorkersList => {
self.execute_workers_list(matches).await;
}
CliCommand::WorkersRecycle => {
self.execute_workers_recycle(matches).await;
self.execute_worker_task_upload_chunk(matches).await
}
CliCommand::WorkerTaskComplete => self.execute_worker_task_complete(matches).await,
CliCommand::WorkerTaskAddOutput => self.execute_worker_task_add_output(matches).await,
CliCommand::WorkersList => self.execute_workers_list(matches).await,
CliCommand::WorkersRecycle => self.execute_workers_recycle(matches).await,
}
}
pub async fn execute_control_hold(&self, matches: &clap::ArgMatches) {
pub async fn execute_control_hold(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.control_hold();
self.over
.execute_control_hold(matches, &mut request)
.unwrap();
self.config.execute_control_hold(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_control_resume(&self, matches: &clap::ArgMatches) {
pub async fn execute_control_resume(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.control_resume();
self.over
.execute_control_resume(matches, &mut request)
.unwrap();
self.config.execute_control_resume(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_task_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_task_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.task_get();
if let Some(value) = matches.get_one::<String>("task") {
request = request.task(value.clone());
}
self.over.execute_task_get(matches, &mut request).unwrap();
self.config.execute_task_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_tasks_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_tasks_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.tasks_get();
self.over.execute_tasks_get(matches, &mut request).unwrap();
self.config.execute_tasks_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_task_submit(&self, matches: &clap::ArgMatches) {
pub async fn execute_task_submit(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.task_submit();
if let Some(value) = matches.get_one::<String>("name") {
request = request.body_map(|body| body.name(value.clone()))
@ -464,21 +426,21 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_task_submit(matches, &mut request)
.unwrap();
self.config.execute_task_submit(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_task_events_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_task_events_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.task_events_get();
if let Some(value) = matches.get_one::<u32>("minseq") {
request = request.minseq(value.clone());
@ -488,41 +450,45 @@ impl<T: CliOverride> Cli<T> {
request = request.task(value.clone());
}
self.over
.execute_task_events_get(matches, &mut request)
.unwrap();
self.config.execute_task_events_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_task_outputs_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_task_outputs_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.task_outputs_get();
if let Some(value) = matches.get_one::<String>("task") {
request = request.task(value.clone());
}
self.over
.execute_task_outputs_get(matches, &mut request)
.unwrap();
self.config
.execute_task_outputs_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_task_output_download(&self, matches: &clap::ArgMatches) {
pub async fn execute_task_output_download(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.task_output_download();
if let Some(value) = matches.get_one::<String>("output") {
request = request.output(value.clone());
@ -532,21 +498,21 @@ impl<T: CliOverride> Cli<T> {
request = request.task(value.clone());
}
self.over
.execute_task_output_download(matches, &mut request)
.unwrap();
self.config
.execute_task_output_download(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
todo!()
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_user_create(&self, matches: &clap::ArgMatches) {
pub async fn execute_user_create(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.user_create();
if let Some(value) = matches.get_one::<String>("name") {
request = request.body_map(|body| body.name(value.clone()))
@ -558,51 +524,53 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_user_create(matches, &mut request)
.unwrap();
self.config.execute_user_create(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_whoami(&self, matches: &clap::ArgMatches) {
pub async fn execute_whoami(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.whoami();
self.over.execute_whoami(matches, &mut request).unwrap();
self.config.execute_whoami(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_whoami_put_name(&self, matches: &clap::ArgMatches) {
pub async fn execute_whoami_put_name(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.whoami_put_name();
self.over
.execute_whoami_put_name(matches, &mut request)
.unwrap();
self.config.execute_whoami_put_name(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_bootstrap(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_bootstrap(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.worker_bootstrap();
if let Some(value) = matches.get_one::<String>("bootstrap") {
request = request.body_map(|body| body.bootstrap(value.clone()))
@ -618,37 +586,41 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_worker_bootstrap(matches, &mut request)
.unwrap();
self.config
.execute_worker_bootstrap(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_ping(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_ping(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.worker_ping();
self.over
.execute_worker_ping(matches, &mut request)
.unwrap();
self.config.execute_worker_ping(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_task_append(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_task_append(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.worker_task_append();
if let Some(value) = matches.get_one::<String>("payload") {
request = request.body_map(|body| body.payload(value.clone()))
@ -672,41 +644,49 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_worker_task_append(matches, &mut request)
.unwrap();
self.config
.execute_worker_task_append(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_task_upload_chunk(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_task_upload_chunk(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.worker_task_upload_chunk();
if let Some(value) = matches.get_one::<String>("task") {
request = request.task(value.clone());
}
self.over
.execute_worker_task_upload_chunk(matches, &mut request)
.unwrap();
self.config
.execute_worker_task_upload_chunk(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_task_complete(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_task_complete(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.worker_task_complete();
if let Some(value) = matches.get_one::<bool>("failed") {
request = request.body_map(|body| body.failed(value.clone()))
@ -722,21 +702,25 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_worker_task_complete(matches, &mut request)
.unwrap();
self.config
.execute_worker_task_complete(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_worker_task_add_output(&self, matches: &clap::ArgMatches) {
pub async fn execute_worker_task_add_output(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.worker_task_add_output();
if let Some(value) = matches.get_one::<String>("path") {
request = request.body_map(|body| body.path(value.clone()))
@ -756,59 +740,78 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_worker_task_add_output(matches, &mut request)
.unwrap();
self.config
.execute_worker_task_add_output(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_workers_list(&self, matches: &clap::ArgMatches) {
pub async fn execute_workers_list(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.workers_list();
self.over
.execute_workers_list(matches, &mut request)
.unwrap();
self.config.execute_workers_list(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_workers_recycle(&self, matches: &clap::ArgMatches) {
pub async fn execute_workers_recycle(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.workers_recycle();
self.over
.execute_workers_recycle(matches, &mut request)
.unwrap();
self.config.execute_workers_recycle(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn execute_control_hold(
&self,
matches: &clap::ArgMatches,
request: &mut builder::ControlHold,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -816,7 +819,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::ControlResume,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -824,7 +827,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TaskGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -832,7 +835,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TasksGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -840,7 +843,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TaskSubmit,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -848,7 +851,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TaskEventsGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -856,7 +859,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TaskOutputsGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -864,7 +867,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::TaskOutputDownload,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -872,7 +875,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::UserCreate,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -880,7 +883,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::Whoami,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -888,7 +891,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WhoamiPutName,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -896,7 +899,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerBootstrap,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -904,7 +907,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerPing,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -912,7 +915,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerTaskAppend,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -920,7 +923,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerTaskUploadChunk,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -928,7 +931,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerTaskComplete,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -936,7 +939,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkerTaskAddOutput,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -944,7 +947,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkersList,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -952,12 +955,11 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::WorkersRecycle,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
ControlHold,

View File

@ -1,12 +1,12 @@
use crate::keeper_builder::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(client: Client, config: T) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -181,37 +181,19 @@ impl Cli {
.help("XXX"),
)
}
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(client: Client, over: T) -> Self {
Self { client, over }
}
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) {
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) -> anyhow::Result<()> {
match cmd {
CliCommand::Enrol => {
self.execute_enrol(matches).await;
}
CliCommand::GlobalJobs => {
self.execute_global_jobs(matches).await;
}
CliCommand::Ping => {
self.execute_ping(matches).await;
}
CliCommand::ReportFinish => {
self.execute_report_finish(matches).await;
}
CliCommand::ReportOutput => {
self.execute_report_output(matches).await;
}
CliCommand::ReportStart => {
self.execute_report_start(matches).await;
}
CliCommand::Enrol => self.execute_enrol(matches).await,
CliCommand::GlobalJobs => self.execute_global_jobs(matches).await,
CliCommand::Ping => self.execute_ping(matches).await,
CliCommand::ReportFinish => self.execute_report_finish(matches).await,
CliCommand::ReportOutput => self.execute_report_output(matches).await,
CliCommand::ReportStart => self.execute_report_start(matches).await,
}
}
pub async fn execute_enrol(&self, matches: &clap::ArgMatches) {
pub async fn execute_enrol(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.enrol();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
@ -231,57 +213,61 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over.execute_enrol(matches, &mut request).unwrap();
self.config.execute_enrol(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_global_jobs(&self, matches: &clap::ArgMatches) {
pub async fn execute_global_jobs(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.global_jobs();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
}
self.over
.execute_global_jobs(matches, &mut request)
.unwrap();
self.config.execute_global_jobs(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_ping(&self, matches: &clap::ArgMatches) {
pub async fn execute_ping(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.ping();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
}
self.over.execute_ping(matches, &mut request).unwrap();
self.config.execute_ping(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_report_finish(&self, matches: &clap::ArgMatches) {
pub async fn execute_report_finish(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.report_finish();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
@ -305,21 +291,21 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_report_finish(matches, &mut request)
.unwrap();
self.config.execute_report_finish(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_report_output(&self, matches: &clap::ArgMatches) {
pub async fn execute_report_output(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.report_output();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
@ -331,21 +317,21 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_report_output(matches, &mut request)
.unwrap();
self.config.execute_report_output(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_report_start(&self, matches: &clap::ArgMatches) {
pub async fn execute_report_start(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.report_start();
if let Some(value) = matches.get_one::<String>("authorization") {
request = request.authorization(value.clone());
@ -366,27 +352,45 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_report_start(matches, &mut request)
.unwrap();
self.config.execute_report_start(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn execute_enrol(
&self,
matches: &clap::ArgMatches,
request: &mut builder::Enrol,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -394,7 +398,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::GlobalJobs,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -402,7 +406,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::Ping,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -410,7 +414,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::ReportFinish,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -418,7 +422,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::ReportOutput,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -426,12 +430,11 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::ReportStart,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
Enrol,

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
use crate::param_collision_builder::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(client: Client, config: T) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -61,22 +61,14 @@ impl Cli {
)
.long_about("Gets a key")
}
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(client: Client, over: T) -> Self {
Self { client, over }
}
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) {
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) -> anyhow::Result<()> {
match cmd {
CliCommand::KeyGet => {
self.execute_key_get(matches).await;
}
CliCommand::KeyGet => self.execute_key_get(matches).await,
}
}
pub async fn execute_key_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_key_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.key_get();
if let Some(value) = matches.get_one::<bool>("client") {
request = request.client(value.clone());
@ -102,30 +94,49 @@ impl<T: CliOverride> Cli<T> {
request = request.url(value.clone());
}
self.over.execute_key_get(matches, &mut request).unwrap();
self.config.execute_key_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn execute_key_get(
&self,
matches: &clap::ArgMatches,
request: &mut builder::KeyGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
KeyGet,

View File

@ -1,12 +1,12 @@
use crate::param_overrides_builder::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(client: Client, config: T) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -33,22 +33,14 @@ impl Cli {
)
.long_about("Gets a key")
}
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(client: Client, over: T) -> Self {
Self { client, over }
}
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) {
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) -> anyhow::Result<()> {
match cmd {
CliCommand::KeyGet => {
self.execute_key_get(matches).await;
}
CliCommand::KeyGet => self.execute_key_get(matches).await,
}
}
pub async fn execute_key_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_key_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.key_get();
if let Some(value) = matches.get_one::<bool>("key") {
request = request.key(value.clone());
@ -58,30 +50,49 @@ impl<T: CliOverride> Cli<T> {
request = request.unique_key(value.clone());
}
self.over.execute_key_get(matches, &mut request).unwrap();
self.config.execute_key_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("success\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn execute_key_get(
&self,
matches: &clap::ArgMatches,
request: &mut builder::KeyGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
KeyGet,

View File

@ -1,12 +1,12 @@
use crate::propolis_server_builder::*;
pub struct Cli<T: CliOverride = ()> {
pub struct Cli<T: CliConfig> {
client: Client,
over: T,
config: T,
}
impl Cli {
pub fn new(client: Client) -> Self {
Self { client, over: () }
impl<T: CliConfig> Cli<T> {
pub fn new(client: Client, config: T) -> Self {
Self { client, config }
}
pub fn get_command(cmd: CliCommand) -> clap::Command {
@ -137,57 +137,41 @@ impl Cli {
.help("XXX"),
)
}
}
impl<T: CliOverride> Cli<T> {
pub fn new_with_override(client: Client, over: T) -> Self {
Self { client, over }
}
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) {
pub async fn execute(&self, cmd: CliCommand, matches: &clap::ArgMatches) -> anyhow::Result<()> {
match cmd {
CliCommand::InstanceGet => {
self.execute_instance_get(matches).await;
}
CliCommand::InstanceEnsure => {
self.execute_instance_ensure(matches).await;
}
CliCommand::InstanceGet => self.execute_instance_get(matches).await,
CliCommand::InstanceEnsure => self.execute_instance_ensure(matches).await,
CliCommand::InstanceIssueCrucibleSnapshotRequest => {
self.execute_instance_issue_crucible_snapshot_request(matches)
.await;
.await
}
CliCommand::InstanceMigrateStatus => {
self.execute_instance_migrate_status(matches).await;
}
CliCommand::InstanceSerial => {
self.execute_instance_serial(matches).await;
}
CliCommand::InstanceStatePut => {
self.execute_instance_state_put(matches).await;
}
CliCommand::InstanceStateMonitor => {
self.execute_instance_state_monitor(matches).await;
self.execute_instance_migrate_status(matches).await
}
CliCommand::InstanceSerial => self.execute_instance_serial(matches).await,
CliCommand::InstanceStatePut => self.execute_instance_state_put(matches).await,
CliCommand::InstanceStateMonitor => self.execute_instance_state_monitor(matches).await,
}
}
pub async fn execute_instance_get(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_get(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.instance_get();
self.over
.execute_instance_get(matches, &mut request)
.unwrap();
self.config.execute_instance_get(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_instance_ensure(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_ensure(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.instance_ensure();
if let Some(value) = matches.get_one::<String>("cloud-init-bytes") {
request = request.body_map(|body| body.cloud_init_bytes(value.clone()))
@ -200,16 +184,16 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_instance_ensure(matches, &mut request)
.unwrap();
self.config.execute_instance_ensure(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
@ -217,7 +201,7 @@ impl<T: CliOverride> Cli<T> {
pub async fn execute_instance_issue_crucible_snapshot_request(
&self,
matches: &clap::ArgMatches,
) {
) -> anyhow::Result<()> {
let mut request = self.client.instance_issue_crucible_snapshot_request();
if let Some(value) = matches.get_one::<uuid::Uuid>("id") {
request = request.id(value.clone());
@ -227,21 +211,25 @@ impl<T: CliOverride> Cli<T> {
request = request.snapshot_id(value.clone());
}
self.over
.execute_instance_issue_crucible_snapshot_request(matches, &mut request)
.unwrap();
self.config
.execute_instance_issue_crucible_snapshot_request(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_instance_migrate_status(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_migrate_status(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.instance_migrate_status();
if let Some(value) = matches.get_one::<uuid::Uuid>("migration-id") {
request = request.body_map(|body| body.migration_id(value.clone()))
@ -254,25 +242,24 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_instance_migrate_status(matches, &mut request)
.unwrap();
self.config
.execute_instance_migrate_status(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_instance_serial(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_serial(&self, matches: &clap::ArgMatches) -> anyhow::Result<()> {
let mut request = self.client.instance_serial();
self.over
.execute_instance_serial(matches, &mut request)
.unwrap();
self.config.execute_instance_serial(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
@ -284,7 +271,10 @@ impl<T: CliOverride> Cli<T> {
}
}
pub async fn execute_instance_state_put(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_state_put(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.instance_state_put();
if let Some(value) = matches.get_one::<std::path::PathBuf>("json-body") {
let body_txt = std::fs::read_to_string(value).unwrap();
@ -293,21 +283,25 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_instance_state_put(matches, &mut request)
.unwrap();
self.config
.execute_instance_state_put(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
pub async fn execute_instance_state_monitor(&self, matches: &clap::ArgMatches) {
pub async fn execute_instance_state_monitor(
&self,
matches: &clap::ArgMatches,
) -> anyhow::Result<()> {
let mut request = self.client.instance_state_monitor();
if let Some(value) = matches.get_one::<u64>("gen") {
request = request.body_map(|body| body.gen(value.clone()))
@ -320,27 +314,46 @@ impl<T: CliOverride> Cli<T> {
request = request.body(body_value);
}
self.over
.execute_instance_state_monitor(matches, &mut request)
.unwrap();
self.config
.execute_instance_state_monitor(matches, &mut request)?;
let result = request.send().await;
match result {
Ok(r) => {
println!("success\n{:#?}", r)
self.config.item_success(&r);
Ok(())
}
Err(r) => {
println!("error\n{:#?}", r)
self.config.item_error(&r);
Err(anyhow::Error::new(r))
}
}
}
}
pub trait CliOverride {
pub trait CliConfig {
fn item_success<T>(&self, value: &ResponseValue<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn item_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_start<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_item<T>(&self, value: &T)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_success<T>(&self)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn list_end_error<T>(&self, value: &Error<T>)
where
T: schemars::JsonSchema + serde::Serialize + std::fmt::Debug;
fn execute_instance_get(
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceGet,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -348,7 +361,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceEnsure,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -356,7 +369,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceIssueCrucibleSnapshotRequest,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -364,7 +377,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceMigrateStatus,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -372,7 +385,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceSerial,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -380,7 +393,7 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceStatePut,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
@ -388,12 +401,11 @@ pub trait CliOverride {
&self,
matches: &clap::ArgMatches,
request: &mut builder::InstanceStateMonitor,
) -> Result<(), String> {
) -> anyhow::Result<()> {
Ok(())
}
}
impl CliOverride for () {}
#[derive(Copy, Clone, Debug)]
pub enum CliCommand {
InstanceGet,