wrpc

Trait Invoke

Source
pub trait Invoke: Send + Sync {
    type Context: Send + Sync;
    type Outgoing: AsyncWrite + Index<Self::Outgoing> + Send + Sync + Unpin + 'static;
    type Incoming: AsyncRead + Index<Self::Incoming> + Send + Sync + Unpin + 'static;

    // Required method
    fn invoke<P>(
        &self,
        cx: Self::Context,
        instance: &str,
        func: &str,
        params: Bytes,
        paths: impl AsRef<[P]> + Send,
    ) -> impl Future<Output = Result<(Self::Outgoing, Self::Incoming), Error>> + Send
       where P: AsRef<[Option<usize>]> + Send + Sync;
}
Expand description

Client-side handle to a wRPC transport

Required Associated Types§

Source

type Context: Send + Sync

Transport-specific invocation context

Source

type Outgoing: AsyncWrite + Index<Self::Outgoing> + Send + Sync + Unpin + 'static

Outgoing multiplexed byte stream

Source

type Incoming: AsyncRead + Index<Self::Incoming> + Send + Sync + Unpin + 'static

Incoming multiplexed byte stream

Required Methods§

Source

fn invoke<P>( &self, cx: Self::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> impl Future<Output = Result<(Self::Outgoing, Self::Incoming), Error>> + Send
where P: AsRef<[Option<usize>]> + Send + Sync,

Invoke function func on instance instance

Note, that compilation of code calling methods on Invoke implementations within Send async functions may fail with hard-to-debug errors due to a compiler bug: https://github.com/rust-lang/rust/issues/96865

The following fails to compile with rustc 1.78.0:

use core::future::Future;

fn invoke_send<T>() -> impl Future<Output = anyhow::Result<(T::Outgoing, T::Incoming)>> + Send
where
    T: wrpc_transport::Invoke<Context = ()> + Default,
{
    async { T::default().invoke((), "compiler-bug", "free", "since".into(), [[Some(2024)].as_slice(); 0]).await }
}
async { T::default().invoke((), "compiler-bug", "free", "since".into(), [[Some(2024)].as_slice(); 0]).await }
|     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `AsRef` is not general enough
 |
 = note: `[&'0 [Option<usize>]; 0]` must implement `AsRef<[&'1 [Option<usize>]]>`, for any two lifetimes `'0` and `'1`...
 = note: ...but it actually implements `AsRef<[&[Option<usize>]]>`

The fix is to call send provided by send_future::SendFuture, re-exported by this crate, on the future before awaiting:

use core::future::Future;
use wrpc_transport::SendFuture as _;

fn invoke_send<T>() -> impl Future<Output = anyhow::Result<(T::Outgoing, T::Incoming)>> + Send
where
    T: wrpc_transport::Invoke<Context = ()> + Default,
{
    async { T::default().invoke((), "compiler-bug", "free", "since".into(), [[Some(2024)].as_slice(); 0]).send().await }
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementations on Foreign Types§

Source§

impl Invoke for &Client

Source§

type Context = ()

Source§

type Outgoing = Outgoing

Source§

type Incoming = Incoming

Source§

async fn invoke<P>( &self, __arg1: <&Client as Invoke>::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> Result<(<&Client as Invoke>::Outgoing, <&Client as Invoke>::Incoming), Error>
where P: AsRef<[Option<usize>]> + Send + Sync,

Source§

impl Invoke for &Client

Source§

type Context = ()

Source§

type Outgoing = Outgoing

Source§

type Incoming = Incoming

Source§

async fn invoke<P>( &self, __arg1: <&Client as Invoke>::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> Result<(<&Client as Invoke>::Outgoing, <&Client as Invoke>::Incoming), Error>
where P: AsRef<[Option<usize>]> + Send + Sync,

Source§

impl Invoke for Client

Source§

type Context = Option<HeaderMap>

Source§

type Outgoing = ParamWriter

Source§

type Incoming = Reader

Source§

async fn invoke<P>( &self, cx: <Client as Invoke>::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> Result<(<Client as Invoke>::Outgoing, <Client as Invoke>::Incoming), Error>
where P: AsRef<[Option<usize>]> + Send + Sync,

Source§

impl Invoke for Client

Source§

type Context = ()

Source§

type Outgoing = Outgoing

Source§

type Incoming = Incoming

Source§

async fn invoke<P>( &self, __arg1: <Client as Invoke>::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> Result<(<Client as Invoke>::Outgoing, <Client as Invoke>::Incoming), Error>
where P: AsRef<[Option<usize>]> + Send + Sync,

Source§

impl Invoke for Client

Source§

type Context = ()

Source§

type Outgoing = Outgoing

Source§

type Incoming = Incoming

Source§

async fn invoke<P>( &self, __arg1: <Client as Invoke>::Context, instance: &str, func: &str, params: Bytes, paths: impl AsRef<[P]> + Send, ) -> Result<(<Client as Invoke>::Outgoing, <Client as Invoke>::Incoming), Error>
where P: AsRef<[Option<usize>]> + Send + Sync,

Implementors§

Source§

impl Invoke for wrpc::transport::frame::tcp::Invocation

Source§

impl Invoke for wrpc::transport::frame::unix::Client<&SocketAddr>

Source§

impl Invoke for wrpc::transport::frame::unix::Client<&Path>

Source§

impl Invoke for wrpc::transport::frame::unix::Client<SocketAddr>

Source§

impl Invoke for wrpc::transport::frame::unix::Client<PathBuf>

Source§

impl Invoke for wrpc::transport::frame::unix::Invocation

Source§

impl<T> Invoke for wrpc::transport::frame::tcp::Client<T>
where T: ToSocketAddrs + Clone + Send + Sync,

Source§

impl<T> Invoke for Timeout<'_, T>
where T: Invoke,

Source§

impl<T> Invoke for TimeoutOwned<T>
where T: Invoke,