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