feox_server/protocol/command/
mod.rs1use crate::protocol::resp::RespValue;
2use bytes::Bytes;
3
4mod client;
5mod executor;
6mod list;
7mod parser;
8
9pub use executor::CommandExecutor;
10
11#[derive(Debug, Clone)]
12pub enum Command {
13 Get(Vec<u8>),
15 Set {
16 key: Vec<u8>,
17 value: Bytes,
18 ex: Option<u64>,
19 px: Option<u64>,
20 },
21 Del(Vec<Vec<u8>>),
22 Exists(Vec<Vec<u8>>),
23
24 Incr(Vec<u8>),
26 IncrBy {
27 key: Vec<u8>,
28 delta: i64,
29 },
30 Decr(Vec<u8>),
31 DecrBy {
32 key: Vec<u8>,
33 delta: i64,
34 },
35
36 Expire {
38 key: Vec<u8>,
39 seconds: u64,
40 },
41 PExpire {
42 key: Vec<u8>,
43 milliseconds: u64,
44 },
45 Ttl(Vec<u8>),
46 PTtl(Vec<u8>),
47 Persist(Vec<u8>),
48
49 MGet(Vec<Vec<u8>>),
51 MSet(Vec<(Vec<u8>, Bytes)>),
52
53 Ping(Option<Bytes>),
55 Echo(Bytes),
56 Info(Option<String>),
57 Config {
58 action: String,
59 args: Vec<Bytes>,
60 },
61 Command,
62 Quit,
63 FlushDb,
64
65 Keys(String), Scan {
68 cursor: Vec<u8>,
69 count: usize,
70 pattern: Option<String>,
71 },
72
73 JsonPatch {
75 key: Vec<u8>,
76 patch: Bytes,
77 },
78 Cas {
79 key: Vec<u8>,
80 expected: Bytes,
81 new_value: Bytes,
82 },
83
84 Auth(Vec<u8>),
86
87 LPush {
89 key: Vec<u8>,
90 values: Vec<Bytes>,
91 },
92 RPush {
93 key: Vec<u8>,
94 values: Vec<Bytes>,
95 },
96 LPop {
97 key: Vec<u8>,
98 count: Option<usize>,
99 },
100 RPop {
101 key: Vec<u8>,
102 count: Option<usize>,
103 },
104 LLen(Vec<u8>),
105 LRange {
106 key: Vec<u8>,
107 start: i64,
108 stop: i64,
109 },
110 LIndex {
111 key: Vec<u8>,
112 index: i64,
113 },
114
115 Subscribe(Vec<Vec<u8>>),
116 Unsubscribe(Option<Vec<Vec<u8>>>),
117 PSubscribe(Vec<Vec<u8>>),
118 PUnsubscribe(Option<Vec<Vec<u8>>>),
119 Publish {
120 channel: Vec<u8>,
121 message: Vec<u8>,
122 },
123 PubSub {
124 subcommand: String,
125 args: Vec<Vec<u8>>,
126 },
127
128 Client {
130 subcommand: String,
131 args: Vec<Vec<u8>>,
132 },
133}
134
135impl Command {
136 #[inline(always)]
138 pub fn from_resp(value: RespValue) -> Result<Self, String> {
139 parser::parse_command(value)
140 }
141
142 pub fn is_pubsub_command(&self) -> bool {
144 matches!(
145 self,
146 Command::Subscribe(_)
147 | Command::Unsubscribe(_)
148 | Command::PSubscribe(_)
149 | Command::PUnsubscribe(_)
150 | Command::Publish { .. }
151 | Command::PubSub { .. }
152 )
153 }
154
155 pub fn is_allowed_in_pubsub_mode(&self) -> bool {
157 matches!(
158 self,
159 Command::Subscribe(_)
160 | Command::Unsubscribe(_)
161 | Command::PSubscribe(_)
162 | Command::PUnsubscribe(_)
163 | Command::Ping(_)
164 | Command::Quit
165 )
166 }
167
168 pub fn to_pubsub_op(self) -> Option<crate::network::PubSubOp> {
170 match self {
171 Command::Subscribe(channels) => Some(crate::network::PubSubOp::Subscribe(channels)),
172 Command::Unsubscribe(channels) => Some(crate::network::PubSubOp::Unsubscribe(channels)),
173 Command::PSubscribe(patterns) => Some(crate::network::PubSubOp::PSubscribe(patterns)),
174 Command::PUnsubscribe(patterns) => {
175 Some(crate::network::PubSubOp::PUnsubscribe(patterns))
176 }
177 Command::Publish { channel, message } => {
178 Some(crate::network::PubSubOp::Publish { channel, message })
179 }
180 Command::PubSub { subcommand, args } => match subcommand.to_uppercase().as_str() {
181 "CHANNELS" => Some(crate::network::PubSubOp::PubSubChannels {
182 pattern: args.first().cloned(),
183 }),
184 "NUMSUB" => Some(crate::network::PubSubOp::PubSubNumSub { channels: args }),
185 "NUMPAT" => Some(crate::network::PubSubOp::PubSubNumPat),
186 _ => None,
187 },
188 _ => None,
189 }
190 }
191}