Macro tor_rpcbase::rpc_invoke_fn
source · macro_rules! rpc_invoke_fn { { $funcname:ident($objtype:ty, $methodtype:ty $(,)?) $([ $($flag:ident),* $(,)?])?; $( $($more:tt)+ )? } => { ... }; { @imp-expand $funcname:ident, $objtype:ty, $methodtype:ty, [] } => { ... }; { @imp-expand $funcname:ident, $objtype:ty, $methodtype:ty, [Updates] } => { ... }; { @final $funcname:ident, $objtype:ty, $methodtype:ty, $($sinkvar:ident)? } => { ... }; }
Expand description
Declare an RPC function that will be used to call a single type of Method on a
single type of Object.
§Example
use tor_rpcbase::{self as rpc};
use futures::sink::{Sink, SinkExt};
use std::sync::Arc;
#[derive(Debug)]
struct ExampleObject {}
#[derive(Debug)]
struct ExampleObject2 {}
rpc::decl_object! {ExampleObject; ExampleObject2;}
#[derive(Debug,serde::Deserialize)]
struct ExampleMethod {}
rpc::decl_method! { "arti:x-example" => ExampleMethod}
impl rpc::Method for ExampleMethod {
type Output = ExampleResult;
type Update = Progress;
}
#[derive(serde::Serialize)]
struct ExampleResult {
text: String,
}
#[derive(serde::Serialize)]
struct Progress(f64);
// Note that the types of this function are very constrained:
// - `obj` must be an Arc<O> for some `Object` type.
// - `mth` must be Box<M> for some `Method` type.
// - `ctx` must be Box<dyn rpc::Context>.
// - The function must be async.
// - The return type must be a Result.
// - The OK variant of the result must M::Output.
// - The Err variant of the result must implement Into<rpc::RpcError>.
async fn example(obj: Arc<ExampleObject>,
method: Box<ExampleMethod>,
ctx: Box<dyn rpc::Context>) -> Result<ExampleResult, rpc::RpcError> {
println!("Running example method!");
Ok(ExampleResult { text: "here is your result".into() })
}
rpc::rpc_invoke_fn!{
example(ExampleObject, ExampleMethod);
}
// You can declare an example that produces updates as well:
// - The fourth argument must be `impl Sink<M::Update> + Unpin`.
async fn example2(obj: Arc<ExampleObject2>,
method: Box<ExampleMethod>,
ctx: Box<dyn rpc::Context>,
mut updates: impl Sink<Progress, Error=rpc::SendUpdateError> + Unpin
) -> Result<ExampleResult, rpc::RpcError> {
updates.send(Progress(0.90)).await?;
Ok(ExampleResult { text: "that was fast, wasn't it?".to_string() })
}
rpc::rpc_invoke_fn! {
example2(ExampleObject2, ExampleMethod) [Updates];
}