pub trait PublishedThrough<Slot> { }Expand description
Membership of a message type in a slot marker’s #[publishes(..)] dictionary: the type may
leave through a slot identified by Slot.
#[derive(OutSlot)] emits one impl per listed type, and the publish builder’s typed entry
point (Slot::message) requires it. That is what keeps
the generated document honest: an unrestricted Out<impl Publisher, Marker> reports the
marker’s dictionary as what the handler sends, so a message outside it would be a publish the
document never declared.
The membership is declared on the message type, with the slot as the parameter, so the compile error names the message that is not in the dictionary.
§Examples
use ruststream::memory::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "chunks.progress")]
struct Progress {
percent: u8,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "billing.invoices")]
struct Invoice {
id: u64,
}
/// `Progress: PublishedThrough<Events>`, and nothing else is.
#[derive(OutSlot)]
#[publishes(Progress)]
struct Events;
#[subscriber("orders")]
async fn track(order: &Order, Out(events): Out<impl Publisher, Events>) -> HandlerOutcome {
tracing::info!(order.id, "tracking");
match events.message(&Progress { percent: 100 }).publish().await {
Ok(()) => HandlerOutcome::ack(),
Err(_) => HandlerOutcome::retry(),
}
}A message outside the dictionary does not compile:
use ruststream::memory::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "chunks.progress")]
struct Progress {
percent: u8,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "billing.invoices")]
struct Invoice {
id: u64,
}
/// `Progress: PublishedThrough<Events>`, and nothing else is.
#[derive(OutSlot)]
#[publishes(Progress)]
struct Events;
#[subscriber("orders")]
async fn track(order: &Order, Out(events): Out<impl Publisher, Events>) -> HandlerOutcome {
// An invoice is not in the slot's dictionary: the publish names it in the error.
match events.message(&Invoice { id: order.id }).publish().await {
Ok(()) => HandlerOutcome::ack(),
Err(_) => HandlerOutcome::retry(),
}
}Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".