Attribute Macro dialectic::Transmitter[][src]

#[Transmitter]

In situations where the transmitting backend for a channel is generic, explicitly writing down all the trait bounds necessary to implement a protocol for that parameterized backend can be a lot of boilerplate. The Transmitter attribute macro abbreviates these bounds by modifying the where clause of the item to which it is attached.

This macro may be attached to any item capable of supporting a where-clause: an enum definition, fn item (top level or in a trait definition or implementation), impl block, struct definition, trait definition, type synonym, or union definition.

Examples

use dialectic::prelude::*;

#[Transmitter(Tx for bool, i64)]
async fn foo<Tx, Rx>(
    chan: Chan<Session!{ send bool; send i64 }, Tx, Rx>
) -> Result<(), Tx::Error>
where
    Rx: Send + 'static,
{
    let chan = chan.send(true).await?;
    let chan = chan.send(42).await?;
    chan.close();
    Ok(())
}

Syntax

The Transmitter attribute takes the name of the transmitter for which the bounds will be generated, an optional calling convention (one of move, ref, or mut), and, optionally, the keyword for followed by a comma-separated list of types.

Some example invocations:

#[Transmitter(Tx)]
#[Transmitter(Tx)]
#[Transmitter(Tx for bool)]
#[Transmitter(Tx for ref bool)]
#[Transmitter(Tx for ref mut bool)]
#[Transmitter(Tx for bool, i64, Vec<String>)]
#[Transmitter(Tx for bool, ref i64, ref mut Vec<String>)]

Expansion

The attribute adds extra bounds to the where-clause of the item to which it is attached (if the item does not have a `where-clause, one will be created containing the bounds).

For a transmitter type Tx, optional calling conventions CN? (none, or one of move, ref, or mut), and types T1, T2, ..., the invocation:

#[Transmitter(Tx for C1? T1, C2? T2, ...)]
fn f<Tx>() {}

…translates to the following bounds:

use dialectic::prelude::*;

fn f<Tx>()
where
    Tx: Transmitter + Send + 'static,
    // For each of the types `T1`, `T2`, ...
    // If the convention is unspecified, `C` is left unspecified;
    // otherwise, we translate into `call_by` conventions using
    // `move` => `Val`, `ref` => `Ref`, and `mut` => `Mut`
    Tx: Transmit<T1, C1>,
    Tx: Transmit<T2, C2>,
    // ...
{}