use bus::ExampleBus; use lifeline::prelude::*; use message::*; use postage::{sink::Sink, stream::Stream}; use service::ExampleService; /// If a service spawns many tasks, it helps to break the run functions up. /// You can do this by defining associated functions on the service type, /// and calliing them with Self::run_something(rx, tx) #[tokio::main] pub async fn main() -> anyhow::Result<()> { let bus = ExampleBus::default(); let _service = ExampleService::spawn(&bus)?; let mut rx = bus.rx::()?; let mut tx = bus.tx::()?; tx.send(ExampleRecv::Hello).await?; let oh_hello = rx.recv().await; assert_eq!(Some(ExampleSend::OhHello), oh_hello); println!("Service says {:?}", oh_hello.unwrap()); Ok(()) } mod bus { use crate::message::*; use lifeline::prelude::*; use postage::broadcast; lifeline_bus!(pub struct ExampleBus); impl Message for ExampleRecv { type Channel = broadcast::Sender; } impl Message for ExampleSend { type Channel = broadcast::Sender; } } mod message { #[derive(Debug, Clone)] pub enum ExampleRecv { Hello, } #[derive(Debug, Clone, Eq, PartialEq)] pub enum ExampleSend { OhHello, } } mod service { use crate::bus::ExampleBus; use crate::message::*; use lifeline::prelude::*; use lifeline::{Receiver, Sender}; pub struct ExampleService { _greet: Lifeline, } impl Service for ExampleService { type Bus = ExampleBus; type Lifeline = anyhow::Result; fn spawn(bus: &Self::Bus) -> Self::Lifeline { let rx = bus.rx::()?; let tx = bus.tx::()?; let _greet = Self::try_task("greet", Self::run_greet(rx, tx)); Ok(Self { _greet }) } } impl ExampleService { async fn run_greet( mut rx: impl Receiver, mut tx: impl Sender, ) -> anyhow::Result<()> { while let Some(recv) = rx.recv().await { match recv { ExampleRecv::Hello => { tx.send(ExampleSend::OhHello).await?; } } } Ok(()) } } }