implement ApiHandler::Async
This commit is contained in:
parent
d9897316b8
commit
7dadea06dd
proxmox-api
@ -18,6 +18,7 @@ serde_json = "1.0"
|
||||
textwrap = "0.11"
|
||||
url = "2.1"
|
||||
|
||||
tokio = { version = "0.2", features = [], optional = true }
|
||||
hyper = { version = "0.13", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
@ -25,5 +26,5 @@ lazy_static = "1.3"
|
||||
|
||||
[features]
|
||||
default = [ "router", "cli" ]
|
||||
router = [ "hyper" ]
|
||||
cli = [ "router", "hyper" ]
|
||||
router = [ "hyper", "tokio" ]
|
||||
cli = [ "router", "hyper", "tokio" ]
|
||||
|
@ -58,6 +58,22 @@ fn handle_simple_command(
|
||||
return Err(err);
|
||||
}
|
||||
},
|
||||
ApiHandler::Async(handler) => {
|
||||
let future = (handler)(params, &cli_cmd.info, &mut rpcenv);
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
match rt.block_on(future) {
|
||||
Ok(value) => {
|
||||
if value != Value::Null {
|
||||
println!("Result: {}", serde_json::to_string_pretty(&value).unwrap());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {}", err);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
ApiHandler::AsyncHttp(_) => {
|
||||
let err_msg = "CliHandler does not support ApiHandler::AsyncHttp - internal error";
|
||||
print_simple_usage_error(prefix, cli_cmd, err_msg);
|
||||
|
@ -29,7 +29,9 @@ pub mod router;
|
||||
|
||||
#[cfg(feature = "router")]
|
||||
#[doc(inline)]
|
||||
pub use router::{ApiFuture, ApiHandler, ApiMethod, Router, SubRoute, SubdirMap};
|
||||
pub use router::{
|
||||
ApiFuture, ApiHandler, ApiMethod, ApiResponseFuture, Router, SubRoute, SubdirMap,
|
||||
};
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
pub mod cli;
|
||||
|
@ -38,6 +38,38 @@ pub type ApiHandlerFn = &'static (dyn Fn(Value, &ApiMethod, &mut dyn RpcEnvironm
|
||||
+ Sync
|
||||
+ 'static);
|
||||
|
||||
/// Asynchronous API handlers
|
||||
///
|
||||
/// Returns a future Value.
|
||||
/// ```
|
||||
/// # use failure::*;
|
||||
/// # use serde_json::{json, Value};
|
||||
/// # use proxmox_api::{*, schema::*};
|
||||
/// #
|
||||
/// use futures::*;
|
||||
///
|
||||
/// fn hello_future<'a>(
|
||||
/// param: Value,
|
||||
/// info: &ApiMethod,
|
||||
/// rpcenv: &'a mut dyn RpcEnvironment,
|
||||
/// ) -> ApiFuture<'a> {
|
||||
/// async move {
|
||||
/// let data = json!("hello world!");
|
||||
/// Ok(data)
|
||||
/// }.boxed()
|
||||
/// }
|
||||
///
|
||||
/// const API_METHOD_HELLO_FUTURE: ApiMethod = ApiMethod::new(
|
||||
/// &ApiHandler::Async(&hello_future),
|
||||
/// &ObjectSchema::new("Hello World Example (async)", &[])
|
||||
/// );
|
||||
/// ```
|
||||
pub type ApiAsyncHandlerFn = &'static (dyn for<'a> Fn(Value, &'static ApiMethod, &'a mut dyn RpcEnvironment) -> ApiFuture<'a>
|
||||
+ Send
|
||||
+ Sync);
|
||||
|
||||
pub type ApiFuture<'a> = Pin<Box<dyn Future<Output = Result<Value, failure::Error>> + Send + 'a>>;
|
||||
|
||||
/// Asynchronous HTTP API handlers
|
||||
///
|
||||
/// They get low level access to request and response data. Use this
|
||||
@ -56,7 +88,7 @@ pub type ApiHandlerFn = &'static (dyn Fn(Value, &ApiMethod, &mut dyn RpcEnvironm
|
||||
/// param: Value,
|
||||
/// info: &ApiMethod,
|
||||
/// rpcenv: Box<dyn RpcEnvironment>,
|
||||
/// ) -> ApiFuture {
|
||||
/// ) -> ApiResponseFuture {
|
||||
/// async move {
|
||||
/// let response = http::Response::builder()
|
||||
/// .status(200)
|
||||
@ -70,17 +102,25 @@ pub type ApiHandlerFn = &'static (dyn Fn(Value, &ApiMethod, &mut dyn RpcEnvironm
|
||||
/// &ObjectSchema::new("Hello World Example (low level)", &[])
|
||||
/// );
|
||||
/// ```
|
||||
pub type ApiAsyncHttpHandlerFn = &'static (dyn Fn(Parts, Body, Value, &'static ApiMethod, Box<dyn RpcEnvironment>) -> ApiFuture
|
||||
pub type ApiAsyncHttpHandlerFn = &'static (dyn Fn(
|
||||
Parts,
|
||||
Body,
|
||||
Value,
|
||||
&'static ApiMethod,
|
||||
Box<dyn RpcEnvironment>,
|
||||
) -> ApiResponseFuture
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static);
|
||||
|
||||
/// The output of an asynchronous API handler is a futrue yielding a `Response`.
|
||||
pub type ApiFuture = Pin<Box<dyn Future<Output = Result<Response<Body>, failure::Error>> + Send>>;
|
||||
pub type ApiResponseFuture =
|
||||
Pin<Box<dyn Future<Output = Result<Response<Body>, failure::Error>> + Send>>;
|
||||
|
||||
/// Enum for different types of API handler functions.
|
||||
pub enum ApiHandler {
|
||||
Sync(ApiHandlerFn),
|
||||
Async(ApiAsyncHandlerFn),
|
||||
AsyncHttp(ApiAsyncHttpHandlerFn),
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user