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)>> + 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)>> + 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: http://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.

Implementors§

Source§

impl Invoke for wrpc_transport::frame::tcp::tokio::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::tokio::Client<T>
where T: ToSocketAddrs + Clone + Send + Sync,

Source§

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

Source§

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