hexeract_core/
envelope.rs1use crate::command::Command;
2use crate::ids::{CorrelationId, MessageId};
3use crate::notification::Notification;
4use crate::query::Query;
5
6#[derive(Debug, Clone)]
11pub struct MessageEnvelope {
12 type_name: &'static str,
13 message_id: MessageId,
14 correlation_id: CorrelationId,
15}
16
17impl MessageEnvelope {
18 #[must_use]
20 pub fn for_command<C: Command>(message_id: MessageId, correlation_id: CorrelationId) -> Self {
21 Self {
22 type_name: std::any::type_name::<C>(),
23 message_id,
24 correlation_id,
25 }
26 }
27
28 #[must_use]
30 pub fn for_query<Q: Query>(message_id: MessageId, correlation_id: CorrelationId) -> Self {
31 Self {
32 type_name: std::any::type_name::<Q>(),
33 message_id,
34 correlation_id,
35 }
36 }
37
38 #[must_use]
43 pub fn for_notification<N: Notification>(
44 message_id: MessageId,
45 correlation_id: CorrelationId,
46 ) -> Self {
47 Self {
48 type_name: std::any::type_name::<N>(),
49 message_id,
50 correlation_id,
51 }
52 }
53
54 #[must_use]
56 pub fn type_name(&self) -> &'static str {
57 self.type_name
58 }
59
60 #[must_use]
62 pub fn message_id(&self) -> MessageId {
63 self.message_id
64 }
65
66 #[must_use]
68 pub fn correlation_id(&self) -> CorrelationId {
69 self.correlation_id
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 struct Ping;
78 impl Command for Ping {
79 type Output = ();
80 }
81
82 struct Pong;
83 impl Query for Pong {
84 type Output = ();
85 }
86
87 #[derive(Clone)]
88 struct Bell;
89 impl Notification for Bell {}
90
91 #[test]
92 fn for_notification_records_notification_type_name() {
93 let env = MessageEnvelope::for_notification::<Bell>(MessageId::new(), CorrelationId::new());
94 assert!(env.type_name().ends_with("::Bell"));
95 }
96
97 #[test]
98 fn for_command_records_command_type_name() {
99 let env = MessageEnvelope::for_command::<Ping>(MessageId::new(), CorrelationId::new());
100 assert!(env.type_name().ends_with("::Ping"));
101 }
102
103 #[test]
104 fn for_query_records_query_type_name() {
105 let env = MessageEnvelope::for_query::<Pong>(MessageId::new(), CorrelationId::new());
106 assert!(env.type_name().ends_with("::Pong"));
107 }
108
109 #[test]
110 fn envelope_preserves_identifiers() {
111 let msg = MessageId::new();
112 let corr = CorrelationId::new();
113 let env = MessageEnvelope::for_command::<Ping>(msg, corr);
114 assert_eq!(env.message_id(), msg);
115 assert_eq!(env.correlation_id(), corr);
116 }
117
118 #[test]
119 fn envelope_is_clone() {
120 let env = MessageEnvelope::for_command::<Ping>(MessageId::new(), CorrelationId::new());
121 let cloned = env.clone();
122 assert_eq!(env.message_id(), cloned.message_id());
123 assert_eq!(env.type_name(), cloned.type_name());
124 }
125}