1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9#[repr(u8)]
10pub enum OpCode {
11 Auth = 0x01,
13 AuthOk = 0x02,
14 AuthFail = 0x03,
15
16 SelectDb = 0x10,
18 CreateDb = 0x11,
19 DbOk = 0x12,
20 ListDb = 0x13,
21 ListDbResult = 0x14,
22
23 Remember = 0x20,
25 RememberOk = 0x21,
26 RememberBatch = 0x22,
27
28 Recall = 0x30,
30 RecallResult = 0x31,
31 RecallEnd = 0x32,
32
33 Relate = 0x40,
35 RelateOk = 0x41,
36 Edges = 0x42,
37 EdgesResult = 0x43,
38
39 Forget = 0x50,
41 ForgetOk = 0x51,
42
43 SessionStart = 0x60,
45 SessionEnd = 0x61,
46 SessionOk = 0x62,
47
48 Think = 0x70,
50 ThinkResult = 0x71,
51
52 Subscribe = 0x80,
54 Event = 0x81,
55 Unsubscribe = 0x82,
56
57 Conflicts = 0x90,
59 Resolve = 0x91,
60 ConflictResult = 0x92,
61
62 Personality = 0xA0,
64 Stats = 0xA1,
65 InfoResult = 0xA2,
66
67 ClusterHello = 0xC0, ClusterHelloOk = 0xC1, OplogPull = 0xC2, OplogPullResult = 0xC3, OplogPush = 0xC4, OplogPushOk = 0xC5, Heartbeat = 0xC6, HeartbeatAck = 0xC7, RequestVote = 0xC8, VoteGranted = 0xC9, VoteDenied = 0xCA, ClusterStatus = 0xCB, ClusterStatusResult = 0xCC,
81 ReadOnlyError = 0xCD, ClusterDatabaseList = 0xCE, ClusterDatabaseListResult = 0xCF, Error = 0xF0,
87 Ping = 0xF1,
88 Pong = 0xF2,
89}
90
91impl OpCode {
92 pub fn from_u8(byte: u8) -> Option<Self> {
93 match byte {
94 0x01 => Some(Self::Auth),
95 0x02 => Some(Self::AuthOk),
96 0x03 => Some(Self::AuthFail),
97
98 0x10 => Some(Self::SelectDb),
99 0x11 => Some(Self::CreateDb),
100 0x12 => Some(Self::DbOk),
101 0x13 => Some(Self::ListDb),
102 0x14 => Some(Self::ListDbResult),
103
104 0x20 => Some(Self::Remember),
105 0x21 => Some(Self::RememberOk),
106 0x22 => Some(Self::RememberBatch),
107
108 0x30 => Some(Self::Recall),
109 0x31 => Some(Self::RecallResult),
110 0x32 => Some(Self::RecallEnd),
111
112 0x40 => Some(Self::Relate),
113 0x41 => Some(Self::RelateOk),
114 0x42 => Some(Self::Edges),
115 0x43 => Some(Self::EdgesResult),
116
117 0x50 => Some(Self::Forget),
118 0x51 => Some(Self::ForgetOk),
119
120 0x60 => Some(Self::SessionStart),
121 0x61 => Some(Self::SessionEnd),
122 0x62 => Some(Self::SessionOk),
123
124 0x70 => Some(Self::Think),
125 0x71 => Some(Self::ThinkResult),
126
127 0x80 => Some(Self::Subscribe),
128 0x81 => Some(Self::Event),
129 0x82 => Some(Self::Unsubscribe),
130
131 0x90 => Some(Self::Conflicts),
132 0x91 => Some(Self::Resolve),
133 0x92 => Some(Self::ConflictResult),
134
135 0xA0 => Some(Self::Personality),
136 0xA1 => Some(Self::Stats),
137 0xA2 => Some(Self::InfoResult),
138
139 0xC0 => Some(Self::ClusterHello),
140 0xC1 => Some(Self::ClusterHelloOk),
141 0xC2 => Some(Self::OplogPull),
142 0xC3 => Some(Self::OplogPullResult),
143 0xC4 => Some(Self::OplogPush),
144 0xC5 => Some(Self::OplogPushOk),
145 0xC6 => Some(Self::Heartbeat),
146 0xC7 => Some(Self::HeartbeatAck),
147 0xC8 => Some(Self::RequestVote),
148 0xC9 => Some(Self::VoteGranted),
149 0xCA => Some(Self::VoteDenied),
150 0xCB => Some(Self::ClusterStatus),
151 0xCC => Some(Self::ClusterStatusResult),
152 0xCD => Some(Self::ReadOnlyError),
153 0xCE => Some(Self::ClusterDatabaseList),
154 0xCF => Some(Self::ClusterDatabaseListResult),
155
156 0xF0 => Some(Self::Error),
157 0xF1 => Some(Self::Ping),
158 0xF2 => Some(Self::Pong),
159
160 _ => None,
161 }
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn roundtrip_all_opcodes() {
171 let all = [
172 OpCode::Auth,
173 OpCode::AuthOk,
174 OpCode::AuthFail,
175 OpCode::SelectDb,
176 OpCode::CreateDb,
177 OpCode::DbOk,
178 OpCode::ListDb,
179 OpCode::ListDbResult,
180 OpCode::Remember,
181 OpCode::RememberOk,
182 OpCode::RememberBatch,
183 OpCode::Recall,
184 OpCode::RecallResult,
185 OpCode::RecallEnd,
186 OpCode::Relate,
187 OpCode::RelateOk,
188 OpCode::Edges,
189 OpCode::EdgesResult,
190 OpCode::Forget,
191 OpCode::ForgetOk,
192 OpCode::SessionStart,
193 OpCode::SessionEnd,
194 OpCode::SessionOk,
195 OpCode::Think,
196 OpCode::ThinkResult,
197 OpCode::Subscribe,
198 OpCode::Event,
199 OpCode::Unsubscribe,
200 OpCode::Conflicts,
201 OpCode::Resolve,
202 OpCode::ConflictResult,
203 OpCode::ClusterHello,
204 OpCode::ClusterHelloOk,
205 OpCode::OplogPull,
206 OpCode::OplogPullResult,
207 OpCode::OplogPush,
208 OpCode::OplogPushOk,
209 OpCode::Heartbeat,
210 OpCode::HeartbeatAck,
211 OpCode::RequestVote,
212 OpCode::VoteGranted,
213 OpCode::VoteDenied,
214 OpCode::ClusterStatus,
215 OpCode::ClusterStatusResult,
216 OpCode::ReadOnlyError,
217 OpCode::ClusterDatabaseList,
218 OpCode::ClusterDatabaseListResult,
219 OpCode::Personality,
220 OpCode::Stats,
221 OpCode::InfoResult,
222 OpCode::Error,
223 OpCode::Ping,
224 OpCode::Pong,
225 ];
226 for op in all {
227 let byte = op as u8;
228 let decoded = OpCode::from_u8(byte)
229 .unwrap_or_else(|| panic!("failed to decode opcode 0x{byte:02X}"));
230 assert_eq!(decoded, op);
231 }
232 }
233}