1mod codec;
2mod types;
3
4pub use codec::IpcCodec;
5pub use types::*;
6
7#[cfg(test)]
8mod tests {
9 use super::*;
10 use bytes::BytesMut;
11 use mxr_core::id::*;
12 use tokio_util::codec::{Decoder, Encoder};
13
14 #[test]
15 fn request_serde_roundtrip() {
16 let variants: Vec<Request> = vec![
17 Request::Ping,
18 Request::Shutdown,
19 Request::ListEnvelopes {
20 label_id: None,
21 account_id: None,
22 limit: 50,
23 offset: 0,
24 },
25 Request::GetEnvelope {
26 message_id: MessageId::new(),
27 },
28 Request::Search {
29 query: "test".to_string(),
30 limit: 10,
31 },
32 ];
33
34 for req in variants {
35 let msg = IpcMessage {
36 id: 1,
37 payload: IpcPayload::Request(req),
38 };
39 let json = serde_json::to_string(&msg).unwrap();
40 let parsed: IpcMessage = serde_json::from_str(&json).unwrap();
41 assert_eq!(parsed.id, 1);
42 }
43 }
44
45 #[test]
46 fn response_serde_roundtrip() {
47 let ok = Response::Ok {
48 data: ResponseData::Pong,
49 };
50 let err = Response::Error {
51 message: "something failed".to_string(),
52 };
53
54 for resp in [ok, err] {
55 let msg = IpcMessage {
56 id: 2,
57 payload: IpcPayload::Response(resp),
58 };
59 let json = serde_json::to_string(&msg).unwrap();
60 let parsed: IpcMessage = serde_json::from_str(&json).unwrap();
61 assert_eq!(parsed.id, 2);
62 }
63 }
64
65 #[test]
66 fn daemon_event_roundtrip() {
67 let events: Vec<DaemonEvent> = vec![
68 DaemonEvent::SyncCompleted {
69 account_id: AccountId::new(),
70 messages_synced: 10,
71 },
72 DaemonEvent::SyncError {
73 account_id: AccountId::new(),
74 error: "timeout".to_string(),
75 },
76 DaemonEvent::MessageUnsnoozed {
77 message_id: MessageId::new(),
78 },
79 ];
80
81 for event in events {
82 let msg = IpcMessage {
83 id: 0,
84 payload: IpcPayload::Event(event),
85 };
86 let json = serde_json::to_string(&msg).unwrap();
87 let _parsed: IpcMessage = serde_json::from_str(&json).unwrap();
88 }
89 }
90
91 #[test]
92 fn codec_encode_decode() {
93 let mut codec = IpcCodec::new();
94 let msg = IpcMessage {
95 id: 42,
96 payload: IpcPayload::Request(Request::Ping),
97 };
98
99 let mut buf = BytesMut::new();
100 codec.encode(msg, &mut buf).unwrap();
101
102 let decoded = codec.decode(&mut buf).unwrap().unwrap();
103 assert_eq!(decoded.id, 42);
104 }
105
106 #[test]
107 fn codec_multiple_messages() {
108 let mut codec = IpcCodec::new();
109 let mut buf = BytesMut::new();
110
111 for i in 0..3 {
112 let msg = IpcMessage {
113 id: i,
114 payload: IpcPayload::Request(Request::Ping),
115 };
116 codec.encode(msg, &mut buf).unwrap();
117 }
118
119 for i in 0..3 {
120 let decoded = codec.decode(&mut buf).unwrap().unwrap();
121 assert_eq!(decoded.id, i);
122 }
123
124 assert!(codec.decode(&mut buf).unwrap().is_none());
126 }
127}