rings_core/message/handlers/
custom.rs1use async_trait::async_trait;
2
3use crate::dht::Did;
4use crate::error::Result;
5use crate::message::effects::CoreEffect;
6use crate::message::effects::PayloadRelayFunctor;
7use crate::message::types::CustomMessage;
8use crate::message::HandleMsg;
9use crate::message::MessageHandler;
10use crate::message::MessagePayload;
11
12pub(crate) fn custom_message_effects<'payload>(
13 local: Did,
14 ctx: &'payload MessagePayload,
15) -> Option<CoreEffect<'payload>> {
16 if ctx.should_forward_from(local) {
17 Some(PayloadRelayFunctor::forward_payload(ctx, None).into())
18 } else {
19 None
20 }
21}
22
23#[cfg_attr(feature = "wasm", async_trait(?Send))]
24#[cfg_attr(not(feature = "wasm"), async_trait)]
25impl HandleMsg<CustomMessage> for MessageHandler {
26 async fn handle(&self, ctx: &MessagePayload, _: &CustomMessage) -> Result<()> {
27 self.run_effects(custom_message_effects(self.dht.did, ctx))
28 .await
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use crate::ecc::SecretKey;
36 use crate::error::Error;
37 use crate::message::Message;
38 use crate::session::SessionSk;
39
40 fn custom_payload(destination: Did) -> Result<MessagePayload> {
41 let key = SecretKey::random();
42 let session_sk = SessionSk::new_with_seckey(&key)?;
43 MessagePayload::new_send(
44 Message::custom(b"hello")?,
45 &session_sk,
46 destination,
47 destination,
48 )
49 }
50
51 #[test]
52 fn local_custom_message_has_no_core_effects() -> Result<()> {
53 let local = SecretKey::random().address().into();
54 let payload = custom_payload(local)?;
55
56 assert!(custom_message_effects(local, &payload).is_none());
57 Ok(())
58 }
59
60 #[test]
61 fn remote_custom_message_forwards_payload() -> Result<()> {
62 let local = SecretKey::random().address().into();
63 let remote = SecretKey::random().address().into();
64 let payload = custom_payload(remote)?;
65 let effect = custom_message_effects(local, &payload)
66 .ok_or_else(|| Error::InvalidMessage("expected ForwardPayload effect".to_string()))?;
67
68 match effect {
69 CoreEffect::Payload(PayloadRelayFunctor::ForwardPayload {
70 payload: forwarded,
71 next_hop,
72 }) => {
73 assert!(std::ptr::eq(forwarded, &payload));
74 assert_eq!(next_hop, None);
75 }
76 effect => {
77 return Err(Error::InvalidMessage(format!(
78 "expected ForwardPayload, got {effect:?}"
79 )))
80 }
81 }
82 Ok(())
83 }
84}