feox_server/protocol/command/
mod.rs1use crate::protocol::resp::RespValue;
2use bytes::Bytes;
3
4mod client;
5mod command_table;
6mod executor;
7mod hash;
8mod list;
9mod parser;
10
11#[allow(unused_imports)]
12pub use command_table::{CommandDef, COMMAND_TABLE};
13pub use executor::CommandExecutor;
14
15#[derive(Debug, Clone)]
16pub enum Command {
17 Get(Vec<u8>),
19 Set {
20 key: Vec<u8>,
21 value: Bytes,
22 ex: Option<u64>,
23 px: Option<u64>,
24 },
25 Del(Vec<Vec<u8>>),
26 Exists(Vec<Vec<u8>>),
27
28 Incr(Vec<u8>),
30 IncrBy {
31 key: Vec<u8>,
32 delta: i64,
33 },
34 Decr(Vec<u8>),
35 DecrBy {
36 key: Vec<u8>,
37 delta: i64,
38 },
39
40 Expire {
42 key: Vec<u8>,
43 seconds: u64,
44 },
45 PExpire {
46 key: Vec<u8>,
47 milliseconds: u64,
48 },
49 Ttl(Vec<u8>),
50 PTtl(Vec<u8>),
51 Persist(Vec<u8>),
52
53 MGet(Vec<Vec<u8>>),
55 MSet(Vec<(Vec<u8>, Bytes)>),
56
57 Ping(Option<Bytes>),
59 Echo(Bytes),
60 Info(Option<String>),
61 Config {
62 action: String,
63 args: Vec<Bytes>,
64 },
65 Command {
66 subcommand: Option<String>,
67 args: Vec<Vec<u8>>,
68 },
69 Quit,
70 FlushDb,
71
72 Keys(String), Scan {
75 cursor: Vec<u8>,
76 count: usize,
77 pattern: Option<String>,
78 },
79
80 JsonPatch {
82 key: Vec<u8>,
83 patch: Bytes,
84 },
85 Cas {
86 key: Vec<u8>,
87 expected: Bytes,
88 new_value: Bytes,
89 },
90
91 Auth(Vec<u8>),
93
94 LPush {
96 key: Vec<u8>,
97 values: Vec<Bytes>,
98 },
99 RPush {
100 key: Vec<u8>,
101 values: Vec<Bytes>,
102 },
103 LPop {
104 key: Vec<u8>,
105 count: Option<usize>,
106 },
107 RPop {
108 key: Vec<u8>,
109 count: Option<usize>,
110 },
111 LLen(Vec<u8>),
112 LRange {
113 key: Vec<u8>,
114 start: i64,
115 stop: i64,
116 },
117 LIndex {
118 key: Vec<u8>,
119 index: i64,
120 },
121
122 Subscribe(Vec<Vec<u8>>),
123 Unsubscribe(Option<Vec<Vec<u8>>>),
124 PSubscribe(Vec<Vec<u8>>),
125 PUnsubscribe(Option<Vec<Vec<u8>>>),
126 Publish {
127 channel: Vec<u8>,
128 message: Vec<u8>,
129 },
130 PubSub {
131 subcommand: String,
132 args: Vec<Vec<u8>>,
133 },
134
135 Client {
137 subcommand: String,
138 args: Vec<Vec<u8>>,
139 },
140
141 Multi,
143 Exec,
144 Discard,
145 Watch(Vec<Vec<u8>>),
146 Unwatch,
147
148 HSet {
150 key: Vec<u8>,
151 fields: Vec<(Vec<u8>, Bytes)>,
152 },
153 HGet {
154 key: Vec<u8>,
155 field: Vec<u8>,
156 },
157 HMGet {
158 key: Vec<u8>,
159 fields: Vec<Vec<u8>>,
160 },
161 HDel {
162 key: Vec<u8>,
163 fields: Vec<Vec<u8>>,
164 },
165 HExists {
166 key: Vec<u8>,
167 field: Vec<u8>,
168 },
169 HGetAll(Vec<u8>),
170 HLen(Vec<u8>),
171 HKeys(Vec<u8>),
172 HVals(Vec<u8>),
173 HIncrBy {
174 key: Vec<u8>,
175 field: Vec<u8>,
176 delta: i64,
177 },
178}
179
180impl Command {
181 #[inline(always)]
183 pub fn from_resp(value: RespValue) -> Result<Self, String> {
184 parser::parse_command(value)
185 }
186
187 pub fn is_pubsub_command(&self) -> bool {
189 matches!(
190 self,
191 Command::Subscribe(_)
192 | Command::Unsubscribe(_)
193 | Command::PSubscribe(_)
194 | Command::PUnsubscribe(_)
195 | Command::Publish { .. }
196 | Command::PubSub { .. }
197 )
198 }
199
200 pub fn is_allowed_in_pubsub_mode(&self) -> bool {
202 matches!(
203 self,
204 Command::Subscribe(_)
205 | Command::Unsubscribe(_)
206 | Command::PSubscribe(_)
207 | Command::PUnsubscribe(_)
208 | Command::Ping(_)
209 | Command::Quit
210 )
211 }
212
213 pub fn to_pubsub_op(self) -> Option<crate::network::PubSubOp> {
215 match self {
216 Command::Subscribe(channels) => Some(crate::network::PubSubOp::Subscribe(channels)),
217 Command::Unsubscribe(channels) => Some(crate::network::PubSubOp::Unsubscribe(channels)),
218 Command::PSubscribe(patterns) => Some(crate::network::PubSubOp::PSubscribe(patterns)),
219 Command::PUnsubscribe(patterns) => {
220 Some(crate::network::PubSubOp::PUnsubscribe(patterns))
221 }
222 Command::Publish { channel, message } => {
223 Some(crate::network::PubSubOp::Publish { channel, message })
224 }
225 Command::PubSub { subcommand, args } => match subcommand.to_uppercase().as_str() {
226 "CHANNELS" => Some(crate::network::PubSubOp::PubSubChannels {
227 pattern: args.first().cloned(),
228 }),
229 "NUMSUB" => Some(crate::network::PubSubOp::PubSubNumSub { channels: args }),
230 "NUMPAT" => Some(crate::network::PubSubOp::PubSubNumPat),
231 _ => None,
232 },
233 _ => None,
234 }
235 }
236}