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];
}