fn echo_with_context(
    wamp_client: Arc<Client>,
    my_state: Arc<RwLock<MyState>>,
) -> wamp_async::RpcFunc {
    Box::new(
        move |args: Option<WampArgs>, kwargs: Option<WampKwArgs>| -> wamp_async::RpcFuture {
            let wamp_client = Arc::clone(&wamp_client);
            let my_state = Arc::clone(&my_state);
            Box::pin(async move {
                // This is the original implementation
                println!("peer.echo {:?} {:?}", args, kwargs);
                // We can mutate the state behind RwLock
                {
                    let mut my_state = my_state.write().unwrap();
                    my_state.calls_count += 1;
                    println!("{:?}", *my_state);
                }
                // We can asynchronously perform any other WAMP action,
                // e.g. recursively call ourselves.
                wamp_client.call("peer.echo", None, None).await.unwrap();

                Ok((args, kwargs))
            })
        },
    )
}
// This is the wrapping boilerplate to pass `my_state` into the closure.
// `wamp_async` registeres the handlers for 'static lifetime, so we have to
// wrap the context (`my_state`) with a reference counter (`Arc`) and mutex (`RwLock`),
// and then we have to *move* the context into the closure, and to bump the
// reference counter (`Arc::clone`) on every call to the handler, and *move*
// the cloned value into the async block which also needs to be pinned.
This is the wrapping boilerplate to pass `my_state` into the closure.
This is the wrapping boilerplate to pass ` my_state ` into the closure .
fn echo_with_context(
    wamp_client: Arc<Client>,
    my_state: Arc<RwLock<MyState>>,
) -> wamp_async::RpcFunc {
    Box::new(
        move |args: Option<WampArgs>, kwargs: Option<WampKwArgs>| -> wamp_async::RpcFuture {
            let wamp_client = Arc::clone(&wamp_client);
            let my_state = Arc::clone(&my_state);
            Box::pin(async move {
                // This is the original implementation
                println!("peer.echo {:?} {:?}", args, kwargs);
                // We can mutate the state behind RwLock
                {
                    let mut my_state = my_state.write().unwrap();
                    my_state.calls_count += 1;
                    println!("{:?}", *my_state);
                }
                // We can asynchronously perform any other WAMP action,
                // e.g. recursively call ourselves.
                wamp_client.call("peer.echo", None, None).await.unwrap();
                Ok((args, kwargs))
            })
        },
    )
}
fn echo_with_context ( wamp_client : Arc < Client > , my_state : Arc < RwLock < MyState > > , ) -> wamp_async :: RpcFunc { Box :: new ( move | args : Option < WampArgs > , kwargs : Option < WampKwArgs > | -> wamp_async :: RpcFuture { let wamp_client = Arc :: clone ( & wamp_client ) ; let my_state = Arc :: clone ( & my_state ) ; Box :: pin ( async move { // This is the original implementation println ! ( " " args kwargs ) ; // We can mutate the state behind RwLock { let mut my_state = my_state . write ( ) . unwrap ( ) ; my_state . calls_count += 1 ; println ! ( " " my_state ) ; } // We can asynchronously perform any other WAMP action, // e.g. recursively call ourselves. wamp_client . call ( " " , None , None ) . await . unwrap ( ) ; Ok ( ( args , kwargs ) ) } ) } , ) }
This is the wrapping boilerplate to pass `my_state` into the closure.
This is the wrapping boilerplate to pass ` my_state ` into the closure .
wamp_client
Arc<Client>
my_state
Arc<RwLock<MyState>>