diff --git a/proxmox-api/src/format.rs b/proxmox-api/src/format.rs index 62a1deec..703c86ee 100644 --- a/proxmox-api/src/format.rs +++ b/proxmox-api/src/format.rs @@ -220,7 +220,7 @@ fn dump_method_definition(method: &str, path: &str, def: Option<&ApiMethod>) -> let mut method = method; - if let ApiHandler::Async(_) = api_method.handler { + if let ApiHandler::AsyncHttp(_) = api_method.handler { method = if method == "POST" { "UPLOAD" } else { method }; method = if method == "GET" { "DOWNLOAD" } else { method }; } diff --git a/proxmox-api/src/lib.rs b/proxmox-api/src/lib.rs index 76fafe6a..6cb8bc6a 100644 --- a/proxmox-api/src/lib.rs +++ b/proxmox-api/src/lib.rs @@ -26,13 +26,64 @@ pub use router::Router; pub use error::HttpError; /// A synchronous API handler gets a json Value as input and returns a json Value as output. +/// +/// Most API handler are synchronous. Use this to define such handler: +/// ``` +/// # use failure::*; +/// # use serde_json::{json, Value}; +/// # use proxmox_api::{*, schema::*}; +/// # +/// fn hello( +/// param: Value, +/// info: &ApiMethod, +/// rpcenv: &mut dyn RpcEnvironment, +/// ) -> Result { +/// Ok(json!("hello world!")) +/// } +/// +/// const API_METHOD_HELLO: ApiMethod = ApiMethod::new( +/// &ApiHandler::Sync(&hello), +/// &ObjectSchema::new("Hello World Example", &[]) +/// ); +/// ``` pub type ApiHandlerFn = &'static (dyn Fn(Value, &ApiMethod, &mut dyn RpcEnvironment) -> Result + Send + Sync + 'static); -/// Asynchronous API handlers get more lower level access to request data. -pub type ApiAsyncHandlerFn = &'static (dyn Fn(Parts, Body, Value, &'static ApiMethod, Box) -> ApiFuture +/// Asynchronous HTTP API handlers +/// +/// They get low level access to request and response data. Use this +/// to implement custom upload/download functions. +/// ``` +/// # use failure::*; +/// # use serde_json::{json, Value}; +/// # use proxmox_api::{*, schema::*}; +/// # +/// use futures::*; +/// use hyper::{Body, Response, http::request::Parts}; +/// +/// fn low_level_hello( +/// parts: Parts, +/// req_body: Body, +/// param: Value, +/// info: &ApiMethod, +/// rpcenv: Box, +/// ) -> ApiFuture { +/// async move { +/// let response = http::Response::builder() +/// .status(200) +/// .body(Body::from("Hello world!"))?; +/// Ok(response) +/// }.boxed() +/// } +/// +/// const API_METHOD_LOW_LEVEL_HELLO: ApiMethod = ApiMethod::new( +/// &ApiHandler::AsyncHttp(&low_level_hello), +/// &ObjectSchema::new("Hello World Example (low level)", &[]) +/// ); +/// ``` +pub type ApiAsyncHttpHandlerFn = &'static (dyn Fn(Parts, Body, Value, &'static ApiMethod, Box) -> ApiFuture + Send + Sync + 'static); @@ -40,9 +91,10 @@ pub type ApiAsyncHandlerFn = &'static (dyn Fn(Parts, Body, Value, &'static ApiMe /// The output of an asynchronous API handler is a futrue yielding a `Response`. pub type ApiFuture = Pin, failure::Error>> + Send>>; +/// Enum for different types of API handler functions. pub enum ApiHandler { Sync(ApiHandlerFn), - Async(ApiAsyncHandlerFn), + AsyncHttp(ApiAsyncHttpHandlerFn), } /// This struct defines synchronous API call which returns the restulkt as json `Value`