#![cfg(feature = "test-util")] use elfo::{config::AnyConfig, prelude::*}; #[message] struct Unit; #[message(ret = Type)] struct ReqUnit; #[message] struct Tuple(u32, u32); #[message(ret = Type)] struct ReqTuple(u32, u32); #[message] struct Struct { a: u32, } #[message(ret = Type)] struct ReqStruct { a: u32, } #[message] enum Enum { A { a: u32 }, B, } #[message(ret = Type)] enum ReqEnum { A { a: u32 }, B, } #[message] #[derive(PartialEq)] enum Type { Unit(u32), Tuple(u32), Struct(u32), Enum(u32), } fn sample() -> Blueprint { ActorGroup::new().exec(|mut ctx| async move { while let Some(envelope) = ctx.recv().await { // Borrowed usage. let _flag = msg!(match &envelope { Unit | Tuple | Struct | ReqStruct => true, _ => false, }); // Regression for "borrowed value does not live long enough". let _a = msg!(match &envelope { Struct { a } => Some(a), _ => None, }); // Check spans. let type_id = 42; // macro's internals msg!(match &envelope { Unit => assert_eq!(type_id, 42), }); // Owned usage. msg!(match envelope { // Unit. Unit => ctx.send(Type::Unit(0)).await.unwrap(), (ReqUnit, token) => ctx.respond(token, Type::Unit(1)), // Tuple. Tuple(a, _) if a == 0 => ctx.send(Type::Tuple(0)).await.unwrap(), _t @ Tuple => ctx.send(Type::Tuple(1)).await.unwrap(), (ReqTuple(a, _), token) if a == 0 => ctx.respond(token, Type::Tuple(2)), (_t @ ReqTuple, token) => ctx.respond(token, Type::Tuple(3)), // Struct. Struct { a } if a == 0 => ctx.send(Type::Struct(0)).await.unwrap(), Struct => ctx.send(Type::Struct(1)).await.unwrap(), (ReqStruct { a }, token) if a == 0 => ctx.respond(token, Type::Struct(2)), (_t @ ReqStruct, token) => ctx.respond(token, Type::Struct(3)), // Enum. Enum::A { a } if a == 0 => ctx.send(Type::Enum(0)).await.unwrap(), Enum::B => ctx.send(Type::Enum(1)).await.unwrap(), (ReqEnum::A { a: _a }, token) => ctx.respond(token, Type::Enum(2)), (_t @ ReqEnum::B, token) => ctx.respond(token, Type::Enum(3)), e @ Enum => ctx .send(match e { Enum::A { .. } => Type::Enum(4), Enum::B => unreachable!(), }) .await .unwrap(), }); } }) } #[tokio::test] async fn it_handles_unit() { let mut proxy = elfo::test::proxy(sample(), AnyConfig::default()).await; proxy.send(Unit).await; assert_msg_eq!(proxy.recv().await, Type::Unit(0)); assert_eq!(proxy.request(ReqUnit).await, Type::Unit(1)); } #[tokio::test] async fn it_handles_tuple() { let mut proxy = elfo::test::proxy(sample(), AnyConfig::default()).await; proxy.send(Tuple(0, 42)).await; assert_msg_eq!(proxy.recv().await, Type::Tuple(0)); proxy.send(Tuple(1, 42)).await; assert_msg_eq!(proxy.recv().await, Type::Tuple(1)); assert_eq!(proxy.request(ReqTuple(0, 42)).await, Type::Tuple(2)); assert_eq!(proxy.request(ReqTuple(1, 42)).await, Type::Tuple(3)); } #[tokio::test] async fn it_handles_struct() { let mut proxy = elfo::test::proxy(sample(), AnyConfig::default()).await; proxy.send(Struct { a: 0 }).await; assert_msg_eq!(proxy.recv().await, Type::Struct(0)); proxy.send(Struct { a: 1 }).await; assert_msg_eq!(proxy.recv().await, Type::Struct(1)); assert_eq!(proxy.request(ReqStruct { a: 0 }).await, Type::Struct(2)); assert_eq!(proxy.request(ReqStruct { a: 1 }).await, Type::Struct(3)); } #[tokio::test] async fn it_handles_enum() { let mut proxy = elfo::test::proxy(sample(), AnyConfig::default()).await; proxy.send(Enum::A { a: 0 }).await; assert_msg_eq!(proxy.recv().await, Type::Enum(0)); proxy.send(Enum::B).await; assert_msg_eq!(proxy.recv().await, Type::Enum(1)); assert_eq!(proxy.request(ReqEnum::A { a: 0 }).await, Type::Enum(2)); assert_eq!(proxy.request(ReqEnum::B).await, Type::Enum(3)); proxy.send(Enum::A { a: 1 }).await; assert_msg_eq!(proxy.recv().await, Type::Enum(4)); }