1use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6use crate::postbox::Message;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9#[serde(tag = "op", rename_all = "snake_case")]
10pub enum Request {
11 Put {
12 key: String,
13 value: String,
14 },
15 Get {
16 key: String,
17 },
18 Del {
19 key: String,
20 },
21 Send {
22 #[serde(default)]
23 from: Option<String>,
24 recipient: String,
25 message: String,
26 },
27 Cron {
28 schedule: String,
29 message: String,
30 },
31 Poll {
32 recipient: String,
33 },
34 PollCron,
35 List {
36 path: String,
37 },
38 Ack {
39 id_or_path: String,
40 },
41 Flush,
42 Ping,
43 Shutdown,
44 TickStart {
45 label: String,
46 },
47 TickEnd,
48 TickStatus,
49 TickLock {
50 key: String,
51 },
52 TickUnlock {
53 key: String,
54 },
55 Event {
56 payload: String,
57 #[serde(default)]
59 ttl: Option<u64>,
60 },
61 AgentMessage {
62 from: String,
63 to: String,
64 payload: String,
65 },
66 WebStatus,
68 WebList,
70 WebRm {
72 name: String,
73 },
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize)]
77#[serde(tag = "status", rename_all = "snake_case")]
78pub enum Response {
79 Ok {
80 #[serde(default, skip_serializing_if = "Option::is_none")]
81 value: Option<String>,
82 #[serde(default, skip_serializing_if = "Option::is_none")]
83 uuid: Option<Uuid>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 found: Option<bool>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
87 dirty: Option<bool>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 tick: Option<u64>,
90 #[serde(default, skip_serializing_if = "Option::is_none")]
91 queued: Option<usize>,
92 #[serde(default, skip_serializing_if = "Vec::is_empty")]
93 messages: Vec<MessageDto>,
94 },
95 Err {
96 error: String,
97 },
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct MessageDto {
102 pub id: Uuid,
103 pub path: String,
104 pub body: String,
105}
106
107impl From<Message> for MessageDto {
108 fn from(m: Message) -> Self {
109 Self {
110 id: m.id,
111 path: m.path.display().to_string(),
112 body: m.body,
113 }
114 }
115}
116
117impl From<MessageDto> for Message {
118 fn from(m: MessageDto) -> Self {
119 Self {
120 id: m.id,
121 path: m.path.into(),
122 body: m.body,
123 }
124 }
125}
126
127pub fn encode_response(response: &Response) -> Result<String, serde_json::Error> {
128 Ok(format!("{}\n", serde_json::to_string(response)?))
129}
130
131pub fn decode_request(line: &str) -> Result<Request, serde_json::Error> {
132 serde_json::from_str(line.trim())
133}
134
135pub fn decode_response(line: &str) -> Result<Response, serde_json::Error> {
136 serde_json::from_str(line.trim())
137}
138
139pub fn ok_empty() -> Response {
140 Response::Ok {
141 value: None,
142 uuid: None,
143 found: None,
144 dirty: None,
145 tick: None,
146 queued: None,
147 messages: vec![],
148 }
149}