use async_trait::async_trait;
use serviceless::{Context, EmptyStream, Handler, Message, Service};
#[derive(Debug, Default)]
pub struct Service0 {}
#[async_trait]
impl Service for Service0 {
type Stream = EmptyStream<Self>;
async fn started(&mut self, _ctx: &mut Context<Self, Self::Stream>) {
println!("Started")
}
async fn stopped(&mut self, _ctx: &mut Context<Self, Self::Stream>) {
println!("Stopped")
}
}
#[derive(Debug)]
pub struct U8(pub u8);
impl Message for U8 {
type Result = U8;
}
#[async_trait]
impl Handler<U8> for Service0 {
async fn handle(&mut self, message: U8, _ctx: &mut Context<Self, Self::Stream>) -> U8 {
U8(message.0 + 2)
}
}
#[derive(Debug)]
pub struct U16(pub u16);
impl Message for U16 {
type Result = U16;
}
#[async_trait]
impl Handler<U16> for Service0 {
async fn handle(&mut self, message: U16, _ctx: &mut Context<Self, Self::Stream>) -> U16 {
U16(message.0 + 300)
}
}
#[tokio::main]
async fn main() {
let srv = Service0::default();
let ctx = Context::new();
let (service_addr, future) = srv.start_by_context(ctx);
let service_handle = tokio::spawn(future);
println!("=== Testing ServiceAddress ===");
let res = service_addr.call(U8(8)).await.unwrap();
println!("ServiceAddress call U8(8): {:?}", res);
let res = service_addr.call(U16(8)).await.unwrap();
println!("ServiceAddress call U16(8): {:?}", res);
println!("\n=== Testing Address<U8> ===");
let (addr_u8, forward_future_u8) = service_addr.clone().into_address::<U8>();
tokio::spawn(forward_future_u8);
let res = addr_u8.call(U8(10)).await.unwrap();
println!("Address<U8> call U8(10): {:?}", res);
addr_u8.send(U8(20)).unwrap();
println!("Address<U8> send U8(20): success");
println!("\n=== Testing Address<U16> ===");
let (addr_u16, forward_future_u16) = service_addr.clone().into_address::<U16>();
tokio::spawn(forward_future_u16);
let res = addr_u16.call(U16(100)).await.unwrap();
println!("Address<U16> call U16(100): {:?}", res);
addr_u16.send(U16(200)).unwrap();
println!("Address<U16> send U16(200): success");
println!("\n=== Testing close_service ===");
assert!(
!service_addr.is_stop(),
"Service should not be stopped before close_service"
);
service_addr.close_service();
assert!(
service_addr.is_stop(),
"Service should be stopped after close_service"
);
println!("close_service called successfully, service is now stopped");
println!("Waiting for service to stop and call stopped hook...");
service_handle.await.unwrap();
println!("Service future completed, stopped hook should have been called");
let result = service_addr.send(U8(30));
assert!(
result.is_err(),
"Sending message after close_service should fail"
);
println!("Verified: sending message after close_service fails as expected");
println!("\n=== All tests completed ===");
}