Also map the reply
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
36966ff86d
commit
9fac3f08a1
2 changed files with 37 additions and 21 deletions
|
|
@ -62,14 +62,13 @@ pub trait InternalMessageHandler {
|
||||||
) -> impl Future<Output = anyhow::Result<InternalMessage>>;
|
) -> impl Future<Output = anyhow::Result<InternalMessage>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MB, IMH> Address<MB> for IMH
|
impl<IMH> Address<IMH::HandledMessages> for IMH
|
||||||
where
|
where
|
||||||
MB: MessageBundle,
|
IMH: InternalMessageHandler,
|
||||||
IMH: InternalMessageHandler<HandledMessages = MB>,
|
|
||||||
{
|
{
|
||||||
fn send<M: Message>(&mut self, message: M) -> impl Future<Output = anyhow::Result<M::Reply>> {
|
fn send<M: Message>(&mut self, message: M) -> impl Future<Output = anyhow::Result<M::Reply>> {
|
||||||
const {
|
const {
|
||||||
let true = <M as IsContainedInBundle<MB>>::IS_CONTAINED else {
|
let true = <M as IsContainedInBundle<IMH::HandledMessages>>::IS_CONTAINED else {
|
||||||
panic!("Message is not contained in MessageBundle",);
|
panic!("Message is not contained in MessageBundle",);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use tytix_core::Address;
|
|
||||||
use tytix_core::InternalMessage;
|
use tytix_core::InternalMessage;
|
||||||
use tytix_core::InternalMessageHandler;
|
use tytix_core::InternalMessageHandler;
|
||||||
use tytix_core::IsContainedInBundle;
|
use tytix_core::IsContainedInBundle;
|
||||||
|
|
@ -9,13 +8,16 @@ use tytix_core::Message;
|
||||||
use tytix_core::MessageBundle;
|
use tytix_core::MessageBundle;
|
||||||
use tytix_core::anyhow;
|
use tytix_core::anyhow;
|
||||||
|
|
||||||
|
pub type ReplyOf<M> = <M as Message>::Reply;
|
||||||
|
|
||||||
pub trait AddressExt<MB> {
|
pub trait AddressExt<MB> {
|
||||||
fn map_message<F, M, R, U>(self, f: F) -> MappedMessage<Self, F, M, R>
|
fn map<M, R, F, U, RF, RU>(self, f: F, r: RF) -> MappedMessage<Self, M, F, U, RF, RU>
|
||||||
where
|
where
|
||||||
F: Fn(M) -> U + 'static,
|
|
||||||
U: Future<Output = R>,
|
|
||||||
M: Message,
|
M: Message,
|
||||||
R: Message + IsContainedInBundle<MB>,
|
R: Message + IsContainedInBundle<MB>,
|
||||||
|
F: FnMut(M) -> U + 'static,
|
||||||
|
U: Future<Output = R>,
|
||||||
|
RF: FnMut(<R as Message>::Reply) -> RU + 'static,
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
fn inspect<F, M, U>(self, f: F) -> Inspect<Self, F, U, M>
|
fn inspect<F, M, U>(self, f: F) -> Inspect<Self, F, U, M>
|
||||||
|
|
@ -25,14 +27,13 @@ pub trait AddressExt<MB> {
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<MB: MessageBundle, A: Address<MB>> AddressExt<MB> for A {
|
impl<MB: MessageBundle, A: InternalMessageHandler<HandledMessages = MB>> AddressExt<MB> for A {
|
||||||
fn map_message<F, M, R, U>(self, f: F) -> MappedMessage<Self, F, M, R>
|
fn map<M, R, F, U, RF, RU>(self, f: F, r: RF) -> MappedMessage<Self, M, F, U, RF, RU>
|
||||||
where
|
where
|
||||||
MB: MessageBundle,
|
|
||||||
F: Fn(M) -> U + 'static,
|
|
||||||
U: Future<Output = R>,
|
|
||||||
M: Message,
|
M: Message,
|
||||||
R: Message + IsContainedInBundle<MB>,
|
R: Message + IsContainedInBundle<MB>,
|
||||||
|
F: FnMut(M) -> U + 'static,
|
||||||
|
RF: FnMut(<R as Message>::Reply) -> RU + 'static,
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
const {
|
const {
|
||||||
|
|
@ -44,6 +45,7 @@ impl<MB: MessageBundle, A: Address<MB>> AddressExt<MB> for A {
|
||||||
MappedMessage {
|
MappedMessage {
|
||||||
address: self,
|
address: self,
|
||||||
func: f,
|
func: f,
|
||||||
|
reply: r,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,10 +93,11 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MappedMessage<A, F, M, R> {
|
pub struct MappedMessage<A, M, F, U, RF, RU> {
|
||||||
address: A,
|
address: A,
|
||||||
func: F,
|
func: F,
|
||||||
_pd: PhantomData<fn(M) -> R>,
|
reply: RF,
|
||||||
|
_pd: PhantomData<fn(M) -> (U, RU)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MappedHandledMessages<MB, M, R> {
|
pub struct MappedHandledMessages<MB, M, R> {
|
||||||
|
|
@ -110,13 +113,15 @@ where
|
||||||
const IDS: tytix_core::BundleChain = MB::IDS.without::<R>().with::<M>();
|
const IDS: tytix_core::BundleChain = MB::IDS.without::<R>().with::<M>();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, F, M, R, U> InternalMessageHandler for MappedMessage<A, F, M, R>
|
impl<A, M, R, F, U, RF, RU> InternalMessageHandler for MappedMessage<A, M, F, U, RF, RU>
|
||||||
where
|
where
|
||||||
A: InternalMessageHandler,
|
A: InternalMessageHandler,
|
||||||
M: Message,
|
M: Message,
|
||||||
R: Message + IsContainedInBundle<A::HandledMessages>,
|
R: Message + IsContainedInBundle<A::HandledMessages>,
|
||||||
F: FnMut(M) -> U,
|
F: FnMut(M) -> U,
|
||||||
U: Future<Output = R>,
|
U: Future<Output = R>,
|
||||||
|
RF: FnMut(<R as Message>::Reply) -> RU,
|
||||||
|
RU: Future<Output = <M as Message>::Reply>,
|
||||||
{
|
{
|
||||||
type HandledMessages = MappedHandledMessages<A::HandledMessages, M, R>;
|
type HandledMessages = MappedHandledMessages<A::HandledMessages, M, R>;
|
||||||
|
|
||||||
|
|
@ -135,7 +140,15 @@ where
|
||||||
async {
|
async {
|
||||||
let msg = msg.await;
|
let msg = msg.await;
|
||||||
|
|
||||||
self.address.handle_message(msg).await
|
let msg_reply = self.address.handle_message(msg).await?;
|
||||||
|
|
||||||
|
let Ok(msg_reply) = msg_reply.into_inner() else {
|
||||||
|
return Err(anyhow::anyhow!("Internal Error: Received the wrong type"));
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg_reply = (self.reply)(msg_reply).await;
|
||||||
|
|
||||||
|
Ok(InternalMessage::new(msg_reply))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +159,7 @@ mod tests {
|
||||||
|
|
||||||
use macro_rules_attribute::apply;
|
use macro_rules_attribute::apply;
|
||||||
use smol_macros::test;
|
use smol_macros::test;
|
||||||
|
use tytix_core::Address;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
@ -180,10 +194,13 @@ mod tests {
|
||||||
async fn check_mapping() {
|
async fn check_mapping() {
|
||||||
static MSG: OnceLock<bool> = OnceLock::new();
|
static MSG: OnceLock<bool> = OnceLock::new();
|
||||||
|
|
||||||
let mut sa = SimpleAddress.map_message(|_b: Bar| {
|
let mut sa = SimpleAddress.map(
|
||||||
let _ = MSG.set(true);
|
|_b: Bar| {
|
||||||
async { Foo }
|
let _ = MSG.set(true);
|
||||||
});
|
async { Foo }
|
||||||
|
},
|
||||||
|
|_a| async {},
|
||||||
|
);
|
||||||
|
|
||||||
sa.send(Bar).await.unwrap();
|
sa.send(Bar).await.unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue