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