diff options
author | Alex Auvolat <lx@deuxfleurs.fr> | 2025-01-31 15:53:02 +0100 |
---|---|---|
committer | Alex Auvolat <lx@deuxfleurs.fr> | 2025-02-03 18:54:51 +0100 |
commit | 7b9c047b113d78dacbece4670b8a1a1cbd771849 (patch) | |
tree | 92e4241de8f981d7011eef3b3871e09175b28656 | |
parent | 10bbb26b303e7bd58ca3396009a66b70a1673c0f (diff) | |
download | garage-7b9c047b113d78dacbece4670b8a1a1cbd771849.tar.gz garage-7b9c047b113d78dacbece4670b8a1a1cbd771849.zip |
cli_v2: add local_api_request with crazy type bound
-rw-r--r-- | src/api/admin/api.rs | 16 | ||||
-rw-r--r-- | src/garage/cli_v2/mod.rs | 38 | ||||
-rw-r--r-- | src/garage/cli_v2/worker.rs | 16 |
3 files changed, 37 insertions, 33 deletions
diff --git a/src/api/admin/api.rs b/src/api/admin/api.rs index 1034f59c..cf136d28 100644 --- a/src/api/admin/api.rs +++ b/src/api/admin/api.rs @@ -10,7 +10,6 @@ use serde::{Deserialize, Serialize}; use garage_rpc::*; use garage_model::garage::Garage; -use garage_util::error::Error as GarageError; use garage_api_common::common_error::CommonErrorDerivative; use garage_api_common::helpers::is_default; @@ -105,21 +104,6 @@ pub struct MultiResponse<RB> { pub error: HashMap<String, String>, } -impl<RB> MultiResponse<RB> { - pub fn into_single_response(self) -> Result<RB, GarageError> { - if let Some((_, e)) = self.error.into_iter().next() { - return Err(GarageError::Message(e)); - } - if self.success.len() != 1 { - return Err(GarageError::Message(format!( - "{} responses returned, expected 1", - self.success.len() - ))); - } - Ok(self.success.into_iter().next().unwrap().1) - } -} - // ********************************************** // Special endpoints // diff --git a/src/garage/cli_v2/mod.rs b/src/garage/cli_v2/mod.rs index b9bf05fe..b175ab38 100644 --- a/src/garage/cli_v2/mod.rs +++ b/src/garage/cli_v2/mod.rs @@ -16,7 +16,7 @@ use garage_rpc::*; use garage_api_admin::api::*; use garage_api_admin::api_server::{AdminRpc as ProxyRpc, AdminRpcResponse as ProxyRpcResponse}; -use garage_api_admin::RequestHandler as AdminApiEndpoint; +use garage_api_admin::RequestHandler; use crate::admin::*; use crate::cli as cli_v1; @@ -74,11 +74,11 @@ impl Cli { } } - pub async fn api_request<T>(&self, req: T) -> Result<<T as AdminApiEndpoint>::Response, Error> + pub async fn api_request<T>(&self, req: T) -> Result<<T as RequestHandler>::Response, Error> where - T: AdminApiEndpoint, + T: RequestHandler, AdminApiRequest: From<T>, - <T as AdminApiEndpoint>::Response: TryFrom<TaggedAdminApiResponse>, + <T as RequestHandler>::Response: TryFrom<TaggedAdminApiResponse>, { let req = AdminApiRequest::from(req); let req_name = req.name(); @@ -88,7 +88,7 @@ impl Cli { .await?? { ProxyRpcResponse::ProxyApiOkResponse(resp) => { - <T as AdminApiEndpoint>::Response::try_from(resp).map_err(|_| { + <T as RequestHandler>::Response::try_from(resp).map_err(|_| { Error::Message(format!("{} returned unexpected response", req_name)) }) } @@ -103,4 +103,32 @@ impl Cli { m => Err(Error::unexpected_rpc_message(m)), } } + + pub async fn local_api_request<T>( + &self, + req: T, + ) -> Result<<T as RequestHandler>::Response, Error> + where + T: RequestHandler, + MultiRequest<T>: RequestHandler<Response = MultiResponse<<T as RequestHandler>::Response>>, + AdminApiRequest: From<MultiRequest<T>>, + <MultiRequest<T> as RequestHandler>::Response: TryFrom<TaggedAdminApiResponse>, + { + let req = MultiRequest { + node: hex::encode(self.rpc_host), + body: req, + }; + let resp = self.api_request(req).await?; + + if let Some((_, e)) = resp.error.into_iter().next() { + return Err(Error::Message(e)); + } + if resp.success.len() != 1 { + return Err(Error::Message(format!( + "{} responses returned, expected 1", + resp.success.len() + ))); + } + Ok(resp.success.into_iter().next().unwrap().1) + } } diff --git a/src/garage/cli_v2/worker.rs b/src/garage/cli_v2/worker.rs index 9db729ec..b94a4f68 100644 --- a/src/garage/cli_v2/worker.rs +++ b/src/garage/cli_v2/worker.rs @@ -27,15 +27,11 @@ impl Cli { pub async fn cmd_list_workers(&self, opt: WorkerListOpt) -> Result<(), Error> { let mut list = self - .api_request(ListWorkersRequest { - node: hex::encode(self.rpc_host), - body: LocalListWorkersRequest { - busy_only: opt.busy, - error_only: opt.errors, - }, + .local_api_request(LocalListWorkersRequest { + busy_only: opt.busy, + error_only: opt.errors, }) .await? - .into_single_response()? .0; list.sort_by_key(|info| { @@ -90,12 +86,8 @@ impl Cli { pub async fn cmd_worker_info(&self, tid: usize) -> Result<(), Error> { let info = self - .api_request(GetWorkerInfoRequest { - node: hex::encode(self.rpc_host), - body: LocalGetWorkerInfoRequest { id: tid as u64 }, - }) + .local_api_request(LocalGetWorkerInfoRequest { id: tid as u64 }) .await? - .into_single_response()? .0; let mut table = vec![]; |