Skip to main content

Outgoing

Derive Macro Outgoing 

Source
#[derive(Outgoing)]
{
    // Attributes available to this derive:
    #[outgoing]
}
Expand description

Derives everything a message type declares about being sent, from one key = value attribute: its destination (OutgoingDestination), its optional typed header contract, and the MessageInfo metadata the generated document reads (the type’s name and doc comment).

The destination decides which positions the publish builder demands at the call site:

  • #[outgoing(name = "orders.done")] fixes it - publisher.message(&done).publish() names nothing.
  • #[outgoing(name = "orders.{tenant}.v1")] declares a space of names - to() opens one setter per placeholder, and the publish appears once the last one is bound.
  • the derive alone declares nothing - the call site names it: .to("orders.archived").

The same declaration decides a reply’s destination: #[subscriber(.., reply)] publishes the return value where its type says, and reply("..") supplies the destination of a reply type that declares none. A reply type derives this in every case; a name template does not resolve there, because the runtime has nothing to bind its placeholders with.

headers = Meta declares the typed header contract: Meta stays an ordinary serde struct the derive does not touch, and the publish builder then demands with_headers(&meta).

Do not combine with #[derive(MessageInfo)] on the same type: this derive already provides the message metadata, and the two produce conflicting impls.

ⓘ
/// A finished order.
#[derive(Outgoing, Serialize)]
#[outgoing(name = "orders.done", headers = OrderMeta)]
struct OrderDone { id: u64 }

#[derive(Outgoing, Serialize)]
#[outgoing(name = "orders.{tenant}.{region}.v1")]
struct OrderPlaced { id: u64 }
// out.message(&placed).to().tenant("acme").region("eu").publish().await?;

#[derive(Outgoing, Serialize)]
struct OrderArchived { id: u64 }
// out.message(&archived).to("orders.archived").publish().await?;