xpx_chain_sdk/models/message/
message.rs1use std::fmt;
8
9use crate::helpers::is_hex;
10
11use super::{MessageType, PlainMessage};
12
13#[typetag::serde]
16pub trait Message: Sync + Send + erased_serde::Serialize
17where
18 Self: fmt::Debug,
19{
20 fn message_type(&self) -> MessageType;
21
22 fn box_clone(&self) -> Box<dyn Message>;
23
24 fn payload(&self) -> String;
25
26 fn payload_to_vec(&self) -> Vec<u8> {
27 let mut buf = Vec::new();
28 let payload_str = self.payload();
29 if is_hex(&payload_str) {
30 buf.extend(hex::decode(&payload_str).unwrap())
31 } else {
32 buf.extend(payload_str.as_bytes())
33 };
34
35 buf
36 }
37
38 fn to_vec(&self) -> Vec<u8> {
39 if self.payload().is_empty() {
40 return vec![];
41 };
42 let mut buf = Vec::new();
43 buf.extend(self.message_type().to_bytes().to_vec());
44 buf.extend(self.payload_to_vec());
45 buf
46 }
47
48 fn to_dto(&self) -> String {
49 use MessageType::*;
50
51 if self.payload().is_empty() {
52 return String::new();
53 };
54 match self.message_type() {
55 PlainMessageType | SecureMessageType => {
56 let dto = hex::encode((self.message_type().value() as u8).to_be_bytes());
57 dto + &hex::encode(&self.payload_to_vec())
58 }
59 _ => String::new(),
60 }
61 .to_uppercase()
62 }
63}
64
65impl dyn Message {
66 pub fn empty_message() -> PlainMessage {
67 PlainMessage::default()
68 }
69}
70
71impl Clone for Box<dyn Message + 'static> {
72 fn clone(&self) -> Box<dyn Message + 'static> {
73 self.box_clone()
74 }
75}
76
77impl<'a> PartialEq for &'a dyn Message {
78 fn eq(&self, other: &Self) -> bool {
79 self.to_vec() == other.to_vec()
80 }
81}
82
83impl<'a> PartialEq for Box<dyn Message + 'static> {
84 fn eq(&self, other: &Self) -> bool {
85 self.as_ref() == other.as_ref()
86 }
87}
88
89impl fmt::Display for dyn Message {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(f, "{}", serde_json::to_string_pretty(&self).unwrap_or_default())
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use crate::helpers::utf8_to_hex;
98 use crate::message::{Message, MessageType, PlainMessage, SecureMessage};
99
100 #[test]
101 fn test_should_create_an_plain_message_dto_struct() {
102 let message = PlainMessage::create("test");
103 assert_eq!(message.to_dto(), format!("00{}", utf8_to_hex("test").to_uppercase()));
104 }
105
106 #[test]
107 fn test_should_create_an_encrypted_message_dto_struct() {
108 let message =
109 SecureMessage { r#type: MessageType::SecureMessageType, payload: "test".to_string() };
110 assert_eq!(message.to_dto(), format!("01{}", utf8_to_hex("test").to_uppercase()));
111 }
112}