mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-07 09:51:39 +00:00
api: WIP: don't depend on a specific Body type
For a T which is not directly a Body or Response<Body> type #[api] fn foo() -> T; should not require a specific Body type. Signed-off-by: Wolfgang Bumiller <wry.git@bumiller.com>
This commit is contained in:
parent
c8e11115d2
commit
916f9d945f
@ -18,6 +18,16 @@ pub trait ApiMethodInfo {
|
|||||||
fn call(&self, params: Value) -> super::ApiFuture<Self::Body>;
|
fn call(&self, params: Value) -> super::ApiFuture<Self::Body>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Body: 'static> dyn ApiMethodInfo<Body = Body> {
|
||||||
|
pub fn call_as<ToBody>(&self, params: Value) -> super::ApiFuture<ToBody>
|
||||||
|
where
|
||||||
|
Body: Into<ToBody>,
|
||||||
|
{
|
||||||
|
use futures::future::TryFutureExt;
|
||||||
|
Box::pin(self.call(params).map_ok(|res| res.map(|res| res.into())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Shortcut to not having to type it out. This function signature is just a dummy and not yet
|
/// Shortcut to not having to type it out. This function signature is just a dummy and not yet
|
||||||
/// stabalized!
|
/// stabalized!
|
||||||
pub type CompleteFn = fn(&str) -> Vec<String>;
|
pub type CompleteFn = fn(&str) -> Vec<String>;
|
||||||
@ -289,3 +299,26 @@ impl<Body> ApiType for Response<Body> {
|
|||||||
pub fn get_type_info<T: ApiType>() -> &'static TypeInfo {
|
pub fn get_type_info<T: ApiType>() -> &'static TypeInfo {
|
||||||
T::type_info()
|
T::type_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// API methods can have different body types. For the CLI we don't care whether it is a
|
||||||
|
/// hyper::Body or a bytes::Bytes (also because we don't care for partia bodies etc.), so the
|
||||||
|
/// output needs to be wrapped to a common format. So basically the CLI will only ever see
|
||||||
|
/// `ApiOutput<Bytes>`.
|
||||||
|
pub trait UnifiedApiMethod<Body>: Send + Sync {
|
||||||
|
fn parameters(&self) -> &'static [Parameter];
|
||||||
|
fn call(&self, params: Value) -> super::ApiFuture<Body>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Send + Sync + 'static, Body> UnifiedApiMethod<Body> for T
|
||||||
|
where
|
||||||
|
T: ApiMethodInfo,
|
||||||
|
T::Body: 'static + Into<Body>,
|
||||||
|
{
|
||||||
|
fn parameters(&self) -> &'static [Parameter] {
|
||||||
|
ApiMethodInfo::parameters(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&self, params: Value) -> super::ApiFuture<Body> {
|
||||||
|
(self as &dyn ApiMethodInfo<Body = T::Body>).call_as(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,9 +8,9 @@ use failure::{bail, format_err, Error};
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use super::{ApiMethodInfo, ApiOutput, Parameter};
|
use super::{ApiMethodInfo, ApiOutput, Parameter, UnifiedApiMethod};
|
||||||
|
|
||||||
type MethodInfoRef = &'static dyn UnifiedApiMethod;
|
type MethodInfoRef = &'static dyn UnifiedApiMethod<Bytes>;
|
||||||
|
|
||||||
/// A CLI root node.
|
/// A CLI root node.
|
||||||
pub struct App {
|
pub struct App {
|
||||||
@ -146,30 +146,6 @@ impl SubCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// API methods can have different body types. For the CLI we don't care whether it is a
|
|
||||||
/// hyper::Body or a bytes::Bytes (also because we don't care for partia bodies etc.), so the
|
|
||||||
/// output needs to be wrapped to a common format. So basically the CLI will only ever see
|
|
||||||
/// `ApiOutput<Bytes>`.
|
|
||||||
pub trait UnifiedApiMethod: Send + Sync {
|
|
||||||
fn parameters(&self) -> &'static [Parameter];
|
|
||||||
fn call(&self, params: Value) -> super::ApiFuture<Bytes>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Send + Sync> UnifiedApiMethod for T
|
|
||||||
where
|
|
||||||
T: ApiMethodInfo,
|
|
||||||
T::Body: 'static + Into<Bytes>,
|
|
||||||
{
|
|
||||||
fn parameters(&self) -> &'static [Parameter] {
|
|
||||||
ApiMethodInfo::parameters(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&self, params: Value) -> super::ApiFuture<Bytes> {
|
|
||||||
use futures::future::TryFutureExt;
|
|
||||||
Box::pin(ApiMethodInfo::call(self, params).map_ok(|res| res.map(|body| body.into())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A reference to an API method. Note that when coming from the command line, it is possible to
|
/// A reference to an API method. Note that when coming from the command line, it is possible to
|
||||||
/// match some parameters as positional parameters rather than argument switches, therefor this
|
/// match some parameters as positional parameters rather than argument switches, therefor this
|
||||||
/// contains an ordered list of positional parameters.
|
/// contains an ordered list of positional parameters.
|
||||||
|
Loading…
Reference in New Issue
Block a user