use ruststream::memory::MemoryPublisher;
use ruststream::memory::prelude::*;
use ruststream::testing::TestApp;
use serde::{Deserialize, Serialize};
#[derive(Outgoing, Serialize, Deserialize, PartialEq, Debug)]
struct Order {
id: u64,
}
#[derive(Outgoing, Serialize, Deserialize, PartialEq, Debug)]
struct Receipt {
order_id: u64,
}
struct AppState {
receipts: MemoryPublisher,
}
#[subscriber("orders")]
async fn handle_order(
order: &Order,
ctx: &mut ruststream::runtime::Context<'_, (), AppState>,
) -> HandlerOutcome {
let receipt = Receipt { order_id: order.id };
if ctx
.state()
.receipts
.message(&receipt)
.to("receipts")
.publish()
.await
.is_err()
{
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}
fn service() -> RustStream<ruststream::runtime::Identity, AppState> {
let broker = MemoryBroker::new();
let receipts = broker.publisher();
RustStream::new(AppInfo::new("orders", "0.1.0"))
.on_startup(
move |()| async move { Ok::<_, std::convert::Infallible>(AppState { receipts }) },
)
.with_broker(broker, |b| {
b.include(handle_order);
})
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let tb = TestApp::start(service()).await?;
tb.broker::<MemoryBroker>()
.message(&Order { id: 42 })
.to("orders")
.publish()
.await?;
tb.broker::<MemoryBroker>()
.subscriber("orders")
.assert_called_once()
.with(&Order { id: 42 })
.settled(HandlerOutcome::ack());
tb.broker::<MemoryBroker>()
.published::<Receipt>("receipts")
.assert_called_once()
.with(&Receipt { order_id: 42 });
println!("ok: handler validated, acked, and published a receipt");
Ok(())
}