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 mode: None,
32 explain: false,
33 },
34 ];
35
36 for req in variants {
37 let msg = IpcMessage {
38 id: 1,
39 payload: IpcPayload::Request(req),
40 };
41 let json = serde_json::to_string(&msg).unwrap();
42 let parsed: IpcMessage = serde_json::from_str(&json).unwrap();
43 assert_eq!(parsed.id, 1);
44 }
45 }
46
47 #[test]
48 fn response_serde_roundtrip() {
49 let ok = Response::Ok {
50 data: ResponseData::Pong,
51 };
52 let err = Response::Error {
53 message: "something failed".to_string(),
54 };
55
56 for resp in [ok, err] {
57 let msg = IpcMessage {
58 id: 2,
59 payload: IpcPayload::Response(resp),
60 };
61 let json = serde_json::to_string(&msg).unwrap();
62 let parsed: IpcMessage = serde_json::from_str(&json).unwrap();
63 assert_eq!(parsed.id, 2);
64 }
65 }
66
67 #[test]
68 fn daemon_event_roundtrip() {
69 let events: Vec<DaemonEvent> = vec![
70 DaemonEvent::SyncCompleted {
71 account_id: AccountId::new(),
72 messages_synced: 10,
73 },
74 DaemonEvent::SyncError {
75 account_id: AccountId::new(),
76 error: "timeout".to_string(),
77 },
78 DaemonEvent::MessageUnsnoozed {
79 message_id: MessageId::new(),
80 },
81 ];
82
83 for event in events {
84 let msg = IpcMessage {
85 id: 0,
86 payload: IpcPayload::Event(event),
87 };
88 let json = serde_json::to_string(&msg).unwrap();
89 let _parsed: IpcMessage = serde_json::from_str(&json).unwrap();
90 }
91 }
92
93 #[test]
94 fn codec_encode_decode() {
95 let mut codec = IpcCodec::new();
96 let msg = IpcMessage {
97 id: 42,
98 payload: IpcPayload::Request(Request::Ping),
99 };
100
101 let mut buf = BytesMut::new();
102 codec.encode(msg, &mut buf).unwrap();
103
104 let decoded = codec.decode(&mut buf).unwrap().unwrap();
105 assert_eq!(decoded.id, 42);
106 }
107
108 #[test]
109 fn codec_multiple_messages() {
110 let mut codec = IpcCodec::new();
111 let mut buf = BytesMut::new();
112
113 for i in 0..3 {
114 let msg = IpcMessage {
115 id: i,
116 payload: IpcPayload::Request(Request::Ping),
117 };
118 codec.encode(msg, &mut buf).unwrap();
119 }
120
121 for i in 0..3 {
122 let decoded = codec.decode(&mut buf).unwrap().unwrap();
123 assert_eq!(decoded.id, i);
124 }
125
126 assert!(codec.decode(&mut buf).unwrap().is_none());
128 }
129}