tor_rpcbase

Macro static_rpc_invoke_fn

Source
macro_rules! static_rpc_invoke_fn {
    {
        $( $(@$tag:ident)* $func:expr; )*
    } => { ... };
}
Expand description

Cause one or more RPC functions to be statically registered, each for handling a single Method on a single Object type.

§Example

use tor_rpcbase::{self as rpc, templates::*};
use derive_deftly::Deftly;

use futures::sink::{Sink, SinkExt};
use std::sync::Arc;

#[derive(Debug, Deftly)]
#[derive_deftly(Object)]
struct ExampleObject {}
#[derive(Debug, Deftly)]
#[derive_deftly(Object)]
struct ExampleObject2 {}

#[derive(Debug,serde::Deserialize, Deftly)]
#[derive_deftly(DynMethod)]
#[deftly(rpc(method_name = "arti:x-example"))]
struct ExampleMethod {}
impl rpc::RpcMethod 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 Arc<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: Arc<dyn rpc::Context>,
) -> Result<ExampleResult, rpc::RpcError> {
    println!("Running example method!");
    Ok(ExampleResult { text: "here is your result".into() })
}

rpc::static_rpc_invoke_fn!{example;}

// You can declare an example that produces updates as well:
// - The fourth argument must be `UpdateSink<M::Update>`.
async fn example2(obj: Arc<ExampleObject2>,
                  method: Box<ExampleMethod>,
                  ctx: Arc<dyn rpc::Context>,
                  mut updates: rpc::UpdateSink<Progress>
) -> Result<ExampleResult, rpc::RpcError> {
    updates.send(Progress(0.90)).await?;
    Ok(ExampleResult { text: "that was fast, wasn't it?".to_string() })
}

rpc::static_rpc_invoke_fn! {
    example2;
}

§Syntax:

static_rpc_invoke_fn{
  function;  // zero or morea
  ...
}

where function is an expression referring to a static fn item, with all necessary generics.