@@ -46,11 +46,80 @@ pub struct Message {
46
46
pub event : UnsignedEvent ,
47
47
/// The event id of the 1059 event that contained the message
48
48
pub wrapper_event_id : EventId ,
49
+ /// The state of the message
50
+ pub state : MessageState ,
51
+ }
52
+
53
+ /// The state of the message
54
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
55
+ pub enum MessageState {
56
+ /// The message was created successfully and stored but we don't yet know if it was published to relays.
57
+ Created ,
58
+ /// The message was successfully processed and stored in the database
59
+ Processed ,
60
+ /// The message was deleted by the original sender - via a delete event
61
+ Deleted ,
62
+ }
63
+
64
+ impl fmt:: Display for MessageState {
65
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
66
+ write ! ( f, "{}" , self . as_str( ) )
67
+ }
68
+ }
69
+
70
+ impl MessageState {
71
+ /// Get as `&str`
72
+ pub fn as_str ( & self ) -> & str {
73
+ match self {
74
+ Self :: Created => "created" ,
75
+ Self :: Processed => "processed" ,
76
+ Self :: Deleted => "deleted" ,
77
+ }
78
+ }
79
+ }
80
+
81
+ impl FromStr for MessageState {
82
+ type Err = MessageError ;
83
+
84
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
85
+ match s {
86
+ "created" => Ok ( Self :: Created ) ,
87
+ "processed" => Ok ( Self :: Processed ) ,
88
+ "deleted" => Ok ( Self :: Deleted ) ,
89
+ _ => Err ( MessageError :: InvalidParameters ( format ! (
90
+ "Invalid message state: {}" ,
91
+ s
92
+ ) ) ) ,
93
+ }
94
+ }
95
+ }
96
+
97
+ impl Serialize for MessageState {
98
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
99
+ where
100
+ S : Serializer ,
101
+ {
102
+ serializer. serialize_str ( self . as_str ( ) )
103
+ }
104
+ }
105
+
106
+ impl < ' de > Deserialize < ' de > for MessageState {
107
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
108
+ where
109
+ D : Deserializer < ' de > ,
110
+ {
111
+ let s: String = String :: deserialize ( deserializer) ?;
112
+ Self :: from_str ( & s) . map_err ( serde:: de:: Error :: custom)
113
+ }
49
114
}
50
115
51
116
/// The Processing State of the message,
52
117
#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
53
118
pub enum ProcessedMessageState {
119
+ /// The processed message (and message) was created successfully and stored but we don't yet know if it was published to relays.
120
+ /// This state only happens when you are sending a message. Since we can't decrypt messages from ourselves in MLS groups,
121
+ /// once we see this message we mark it as processed but skip the rest of the processing.
122
+ Created ,
54
123
/// The message was successfully processed and stored in the database
55
124
Processed ,
56
125
/// The message failed to be processed and stored in the database
@@ -67,6 +136,7 @@ impl ProcessedMessageState {
67
136
/// Get as `&str`
68
137
pub fn as_str ( & self ) -> & str {
69
138
match self {
139
+ Self :: Created => "created" ,
70
140
Self :: Processed => "processed" ,
71
141
Self :: Failed => "failed" ,
72
142
}
@@ -78,6 +148,7 @@ impl FromStr for ProcessedMessageState {
78
148
79
149
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
80
150
match s {
151
+ "created" => Ok ( Self :: Created ) ,
81
152
"processed" => Ok ( Self :: Processed ) ,
82
153
"failed" => Ok ( Self :: Failed ) ,
83
154
_ => Err ( MessageError :: InvalidParameters ( format ! (
@@ -113,8 +184,104 @@ mod tests {
113
184
114
185
use super :: * ;
115
186
187
+ #[ test]
188
+ fn test_message_state_from_str ( ) {
189
+ assert_eq ! (
190
+ MessageState :: from_str( "created" ) . unwrap( ) ,
191
+ MessageState :: Created
192
+ ) ;
193
+ assert_eq ! (
194
+ MessageState :: from_str( "processed" ) . unwrap( ) ,
195
+ MessageState :: Processed
196
+ ) ;
197
+ assert_eq ! (
198
+ MessageState :: from_str( "deleted" ) . unwrap( ) ,
199
+ MessageState :: Deleted
200
+ ) ;
201
+
202
+ let err = MessageState :: from_str ( "invalid" ) . unwrap_err ( ) ;
203
+ match err {
204
+ MessageError :: InvalidParameters ( msg) => {
205
+ assert ! ( msg. contains( "Invalid message state: invalid" ) ) ;
206
+ }
207
+ _ => panic ! ( "Expected InvalidParameters error" ) ,
208
+ }
209
+ }
210
+
211
+ #[ test]
212
+ fn test_message_state_to_string ( ) {
213
+ assert_eq ! ( MessageState :: Created . to_string( ) , "created" ) ;
214
+ assert_eq ! ( MessageState :: Processed . to_string( ) , "processed" ) ;
215
+ assert_eq ! ( MessageState :: Deleted . to_string( ) , "deleted" ) ;
216
+ }
217
+
218
+ #[ test]
219
+ fn test_message_state_serialization ( ) {
220
+ let created = MessageState :: Created ;
221
+ let serialized = serde_json:: to_string ( & created) . unwrap ( ) ;
222
+ assert_eq ! ( serialized, r#""created""# ) ;
223
+
224
+ let processed = MessageState :: Processed ;
225
+ let serialized = serde_json:: to_string ( & processed) . unwrap ( ) ;
226
+ assert_eq ! ( serialized, r#""processed""# ) ;
227
+
228
+ let deleted = MessageState :: Deleted ;
229
+ let serialized = serde_json:: to_string ( & deleted) . unwrap ( ) ;
230
+ assert_eq ! ( serialized, r#""deleted""# ) ;
231
+ }
232
+
233
+ #[ test]
234
+ fn test_message_state_deserialization ( ) {
235
+ let created: MessageState = serde_json:: from_str ( r#""created""# ) . unwrap ( ) ;
236
+ assert_eq ! ( created, MessageState :: Created ) ;
237
+
238
+ let processed: MessageState = serde_json:: from_str ( r#""processed""# ) . unwrap ( ) ;
239
+ assert_eq ! ( processed, MessageState :: Processed ) ;
240
+
241
+ let deleted: MessageState = serde_json:: from_str ( r#""deleted""# ) . unwrap ( ) ;
242
+ assert_eq ! ( deleted, MessageState :: Deleted ) ;
243
+
244
+ // Test invalid state
245
+ let result = serde_json:: from_str :: < MessageState > ( r#""invalid""# ) ;
246
+ assert ! ( result. is_err( ) ) ;
247
+ }
248
+
249
+ #[ test]
250
+ fn test_message_serialization ( ) {
251
+ // Create a message to test serialization
252
+ let pubkey =
253
+ PublicKey :: from_hex ( "8a9de562cbbed225b6ea0118dd3997a02df92c0bffd2224f71081a7450c3e549" )
254
+ . unwrap ( ) ;
255
+ let message = Message {
256
+ id : EventId :: all_zeros ( ) ,
257
+ pubkey : pubkey. clone ( ) ,
258
+ kind : Kind :: MlsGroupMessage ,
259
+ mls_group_id : vec ! [ 1 , 2 , 3 , 4 ] ,
260
+ created_at : Timestamp :: now ( ) ,
261
+ content : "Test message" . to_string ( ) ,
262
+ tags : Tags :: new ( ) ,
263
+ event : UnsignedEvent :: new (
264
+ pubkey,
265
+ Timestamp :: now ( ) ,
266
+ Kind :: MlsGroupMessage ,
267
+ Tags :: new ( ) ,
268
+ "Test message" . to_string ( ) ,
269
+ ) ,
270
+ wrapper_event_id : EventId :: all_zeros ( ) ,
271
+ state : MessageState :: Created ,
272
+ } ;
273
+
274
+ let serialized = serde_json:: to_value ( & message) . unwrap ( ) ;
275
+ assert_eq ! ( serialized[ "state" ] , json!( "created" ) ) ;
276
+ assert_eq ! ( serialized[ "content" ] , json!( "Test message" ) ) ;
277
+ }
278
+
116
279
#[ test]
117
280
fn test_processed_message_state_from_str ( ) {
281
+ assert_eq ! (
282
+ ProcessedMessageState :: from_str( "created" ) . unwrap( ) ,
283
+ ProcessedMessageState :: Created
284
+ ) ;
118
285
assert_eq ! (
119
286
ProcessedMessageState :: from_str( "processed" ) . unwrap( ) ,
120
287
ProcessedMessageState :: Processed
@@ -135,12 +302,17 @@ mod tests {
135
302
136
303
#[ test]
137
304
fn test_processed_message_state_to_string ( ) {
305
+ assert_eq ! ( ProcessedMessageState :: Created . to_string( ) , "created" ) ;
138
306
assert_eq ! ( ProcessedMessageState :: Processed . to_string( ) , "processed" ) ;
139
307
assert_eq ! ( ProcessedMessageState :: Failed . to_string( ) , "failed" ) ;
140
308
}
141
309
142
310
#[ test]
143
311
fn test_processed_message_state_serialization ( ) {
312
+ let created = ProcessedMessageState :: Created ;
313
+ let serialized = serde_json:: to_string ( & created) . unwrap ( ) ;
314
+ assert_eq ! ( serialized, r#""created""# ) ;
315
+
144
316
let processed = ProcessedMessageState :: Processed ;
145
317
let serialized = serde_json:: to_string ( & processed) . unwrap ( ) ;
146
318
assert_eq ! ( serialized, r#""processed""# ) ;
@@ -152,11 +324,18 @@ mod tests {
152
324
153
325
#[ test]
154
326
fn test_processed_message_state_deserialization ( ) {
327
+ let created: ProcessedMessageState = serde_json:: from_str ( r#""created""# ) . unwrap ( ) ;
328
+ assert_eq ! ( created, ProcessedMessageState :: Created ) ;
329
+
155
330
let processed: ProcessedMessageState = serde_json:: from_str ( r#""processed""# ) . unwrap ( ) ;
156
331
assert_eq ! ( processed, ProcessedMessageState :: Processed ) ;
157
332
158
333
let failed: ProcessedMessageState = serde_json:: from_str ( r#""failed""# ) . unwrap ( ) ;
159
334
assert_eq ! ( failed, ProcessedMessageState :: Failed ) ;
335
+
336
+ // Test invalid state
337
+ let result = serde_json:: from_str :: < ProcessedMessageState > ( r#""invalid""# ) ;
338
+ assert ! ( result. is_err( ) ) ;
160
339
}
161
340
162
341
#[ test]
@@ -172,6 +351,50 @@ mod tests {
172
351
173
352
let serialized = serde_json:: to_value ( & processed_message) . unwrap ( ) ;
174
353
assert_eq ! ( serialized[ "state" ] , json!( "processed" ) ) ;
175
- assert_eq ! ( serialized[ "failure_reason" ] , json!( "" ) ) ;
354
+ assert_eq ! ( serialized[ "failure_reason" ] , json!( null) ) ;
355
+
356
+ // Create a failed message with a reason
357
+ let failed_message = ProcessedMessage {
358
+ wrapper_event_id : EventId :: all_zeros ( ) ,
359
+ message_event_id : Some ( EventId :: all_zeros ( ) ) ,
360
+ processed_at : Timestamp :: now ( ) ,
361
+ state : ProcessedMessageState :: Failed ,
362
+ failure_reason : Some ( "Decryption failed" . to_string ( ) ) ,
363
+ } ;
364
+
365
+ let serialized = serde_json:: to_value ( & failed_message) . unwrap ( ) ;
366
+ assert_eq ! ( serialized[ "state" ] , json!( "failed" ) ) ;
367
+ assert_eq ! ( serialized[ "failure_reason" ] , json!( "Decryption failed" ) ) ;
368
+ assert ! ( serialized[ "message_event_id" ] . is_string( ) ) ;
369
+ }
370
+
371
+ #[ test]
372
+ fn test_processed_message_deserialization ( ) {
373
+ let json_str = r#"{
374
+ "wrapper_event_id": "0000000000000000000000000000000000000000000000000000000000000000",
375
+ "message_event_id": null,
376
+ "processed_at": 1677721600,
377
+ "state": "processed",
378
+ "failure_reason": null
379
+ }"# ;
380
+
381
+ let processed_message: ProcessedMessage = serde_json:: from_str ( json_str) . unwrap ( ) ;
382
+ assert_eq ! ( processed_message. state, ProcessedMessageState :: Processed ) ;
383
+ assert_eq ! ( processed_message. failure_reason, None ) ;
384
+
385
+ let json_str = r#"{
386
+ "wrapper_event_id": "0000000000000000000000000000000000000000000000000000000000000000",
387
+ "message_event_id": "0000000000000000000000000000000000000000000000000000000000000000",
388
+ "processed_at": 1677721600,
389
+ "state": "failed",
390
+ "failure_reason": "Decryption failed"
391
+ }"# ;
392
+
393
+ let failed_message: ProcessedMessage = serde_json:: from_str ( json_str) . unwrap ( ) ;
394
+ assert_eq ! ( failed_message. state, ProcessedMessageState :: Failed ) ;
395
+ assert_eq ! (
396
+ failed_message. failure_reason,
397
+ Some ( "Decryption failed" . to_string( ) )
398
+ ) ;
176
399
}
177
400
}
0 commit comments