aleph_types/message/
post.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4#[serde(untagged)]
5pub enum PostType {
6 Amend {
7 #[serde(rename = "ref")]
8 reference: String,
9 },
10 Other {
11 #[serde(rename = "type")]
12 post_type: String,
13 },
14}
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17pub struct PostContent {
18 #[serde(flatten)]
19 pub post_type: PostType,
20 pub content: Option<serde_json::Value>,
21}
22
23impl PostContent {
24 pub fn is_amend(&self) -> bool {
25 matches!(self.post_type, PostType::Amend { .. })
26 }
27
28 pub fn post_type_str(&self) -> &str {
29 match &self.post_type {
30 PostType::Amend { .. } => "amend",
31 PostType::Other { post_type } => post_type,
32 }
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use crate::chain::Chain;
40 use crate::message::base_message::MessageContentEnum;
41 use crate::message::{ContentSource, Message, MessageType};
42 use crate::timestamp::Timestamp;
43 use crate::{address, channel, item_hash, signature};
44 use assert_matches::assert_matches;
45
46 const POST_FIXTURE: &str = include_str!(concat!(
47 env!("CARGO_MANIFEST_DIR"),
48 "/../../fixtures/messages/post/post.json"
49 ));
50
51 const AMEND_FIXTURE: &str = include_str!(concat!(
52 env!("CARGO_MANIFEST_DIR"),
53 "/../../fixtures/messages/post/amend.json"
54 ));
55
56 #[test]
57 fn test_deserialize_post() {
58 let message: Message = serde_json::from_str(POST_FIXTURE).unwrap();
59
60 assert_eq!(
61 message.sender,
62 address!("0xB68B9D4f3771c246233823ed1D3Add451055F9Ef")
63 );
64 assert_eq!(message.chain, Chain::Ethereum);
65 assert_eq!(
66 message.signature,
67 signature!(
68 "0x636728dbea33fa6064f099045421b980dff3c71932cd89c2bf42387ebb6f53890a24e13f16678463876224772b90838c2b9557cd8fc2cdae45509ce8cb89e3fd1b"
69 )
70 );
71 assert_matches!(message.message_type, MessageType::Post);
72 assert_matches!(
73 message.content_source,
74 ContentSource::Inline { item_content: _ }
75 );
76 assert_eq!(
77 message.item_hash,
78 item_hash!("d281eb8a69ba1f4dda2d71aaf3ded06caa92edd690ef3d0632f41aa91167762c")
79 );
80 assert_eq!(message.time, Timestamp::from(1762515431.653));
81 assert_eq!(message.channel, Some(channel!("TEST")));
82
83 assert_eq!(
85 &message.content.address,
86 &address!("0xB68B9D4f3771c246233823ed1D3Add451055F9Ef")
87 );
88 assert_eq!(&message.content.time, &Timestamp::from(1762515431.653));
89 assert_eq!(message.sent_at(), &message.content.time);
90
91 let post_content = match message.content() {
93 MessageContentEnum::Post(content) => content,
94 other => {
95 panic!("Expected MessageContentEnum::Post, got {:?}", other);
96 }
97 };
98
99 #[derive(Deserialize)]
100 struct ContentStruct {
101 body: String,
102 }
103 let deserialized_content =
104 serde_json::from_value::<ContentStruct>(post_content.content.clone().unwrap()).unwrap();
105 assert_eq!(deserialized_content.body, "Hello World");
106
107 assert!(!post_content.is_amend());
108 assert_eq!(
109 post_content.post_type_str(),
110 "05567c5b-0606-4a6e-a639-25734c06e2a0"
111 );
112
113 assert!(!message.confirmed());
115 assert!(message.confirmations.is_empty());
116
117 message.verify_item_hash().unwrap();
118 }
119
120 #[test]
121 fn test_deserialize_amend() {
122 let message: Message = serde_json::from_str(AMEND_FIXTURE).unwrap();
123
124 assert_eq!(
125 message.sender,
126 address!("0xB68B9D4f3771c246233823ed1D3Add451055F9Ef")
127 );
128 assert_eq!(message.chain, Chain::Ethereum);
129 assert_eq!(
130 message.signature,
131 signature!(
132 "0xf4a171d2715f2249c6f78160a83a64fb05c21962acdf3729e373fd4f527ed9f570274dedcc468195ba40a26002be0b72aedf260df74032d4ef5a12cb4ea838831c"
133 )
134 );
135 assert_matches!(message.message_type, MessageType::Post);
136 assert_matches!(
137 message.content_source,
138 ContentSource::Inline { item_content: _ }
139 );
140 assert_eq!(
141 message.item_hash,
142 item_hash!("203291b2581b379997b8a0fda43d3afe27573489ca695b711d67fd1a6311b3dd")
143 );
144 assert_eq!(message.time, Timestamp::from(1762515432.375));
145 assert_eq!(message.channel, Some(channel!("TEST")));
146
147 assert_eq!(
149 &message.content.address,
150 &address!("0xB68B9D4f3771c246233823ed1D3Add451055F9Ef")
151 );
152 assert_eq!(&message.content.time, &Timestamp::from(1762515432.375));
153 assert_eq!(message.sent_at(), &message.content.time);
154
155 let post_content = match message.content() {
157 MessageContentEnum::Post(content) => content,
158 other => {
159 panic!("Expected MessageContentEnum::Post, got {:?}", other);
160 }
161 };
162
163 #[derive(Deserialize)]
164 struct ContentStruct {
165 body: String,
166 }
167 let deserialized_content =
168 serde_json::from_value::<ContentStruct>(post_content.content.clone().unwrap()).unwrap();
169 assert_eq!(deserialized_content.body, "New content !");
170
171 assert!(post_content.is_amend());
172 assert_eq!(post_content.post_type_str(), "amend");
173
174 assert!(!message.confirmed());
176 assert!(message.confirmations.is_empty());
177
178 message.verify_item_hash().unwrap();
179 }
180}