use crate::protocol::resp::RespValue;
use bytes::Bytes;
mod client;
mod executor;
mod list;
mod parser;
pub use executor::CommandExecutor;
#[derive(Debug, Clone)]
pub enum Command {
Get(Vec<u8>),
Set {
key: Vec<u8>,
value: Bytes,
ex: Option<u64>,
px: Option<u64>,
},
Del(Vec<Vec<u8>>),
Exists(Vec<Vec<u8>>),
Incr(Vec<u8>),
IncrBy {
key: Vec<u8>,
delta: i64,
},
Decr(Vec<u8>),
DecrBy {
key: Vec<u8>,
delta: i64,
},
Expire {
key: Vec<u8>,
seconds: u64,
},
PExpire {
key: Vec<u8>,
milliseconds: u64,
},
Ttl(Vec<u8>),
PTtl(Vec<u8>),
Persist(Vec<u8>),
MGet(Vec<Vec<u8>>),
MSet(Vec<(Vec<u8>, Bytes)>),
Ping(Option<Bytes>),
Echo(Bytes),
Info(Option<String>),
Config {
action: String,
args: Vec<Bytes>,
},
Command,
Quit,
FlushDb,
Keys(String), Scan {
cursor: Vec<u8>,
count: usize,
pattern: Option<String>,
},
JsonPatch {
key: Vec<u8>,
patch: Bytes,
},
Cas {
key: Vec<u8>,
expected: Bytes,
new_value: Bytes,
},
Auth(Vec<u8>),
LPush {
key: Vec<u8>,
values: Vec<Bytes>,
},
RPush {
key: Vec<u8>,
values: Vec<Bytes>,
},
LPop {
key: Vec<u8>,
count: Option<usize>,
},
RPop {
key: Vec<u8>,
count: Option<usize>,
},
LLen(Vec<u8>),
LRange {
key: Vec<u8>,
start: i64,
stop: i64,
},
LIndex {
key: Vec<u8>,
index: i64,
},
Subscribe(Vec<Vec<u8>>),
Unsubscribe(Option<Vec<Vec<u8>>>),
PSubscribe(Vec<Vec<u8>>),
PUnsubscribe(Option<Vec<Vec<u8>>>),
Publish {
channel: Vec<u8>,
message: Vec<u8>,
},
PubSub {
subcommand: String,
args: Vec<Vec<u8>>,
},
Client {
subcommand: String,
args: Vec<Vec<u8>>,
},
}
impl Command {
#[inline(always)]
pub fn from_resp(value: RespValue) -> Result<Self, String> {
parser::parse_command(value)
}
pub fn is_pubsub_command(&self) -> bool {
matches!(
self,
Command::Subscribe(_)
| Command::Unsubscribe(_)
| Command::PSubscribe(_)
| Command::PUnsubscribe(_)
| Command::Publish { .. }
| Command::PubSub { .. }
)
}
pub fn is_allowed_in_pubsub_mode(&self) -> bool {
matches!(
self,
Command::Subscribe(_)
| Command::Unsubscribe(_)
| Command::PSubscribe(_)
| Command::PUnsubscribe(_)
| Command::Ping(_)
| Command::Quit
)
}
pub fn to_pubsub_op(self) -> Option<crate::network::PubSubOp> {
match self {
Command::Subscribe(channels) => Some(crate::network::PubSubOp::Subscribe(channels)),
Command::Unsubscribe(channels) => Some(crate::network::PubSubOp::Unsubscribe(channels)),
Command::PSubscribe(patterns) => Some(crate::network::PubSubOp::PSubscribe(patterns)),
Command::PUnsubscribe(patterns) => {
Some(crate::network::PubSubOp::PUnsubscribe(patterns))
}
Command::Publish { channel, message } => {
Some(crate::network::PubSubOp::Publish { channel, message })
}
Command::PubSub { subcommand, args } => match subcommand.to_uppercase().as_str() {
"CHANNELS" => Some(crate::network::PubSubOp::PubSubChannels {
pattern: args.first().cloned(),
}),
"NUMSUB" => Some(crate::network::PubSubOp::PubSubNumSub { channels: args }),
"NUMPAT" => Some(crate::network::PubSubOp::PubSubNumPat),
_ => None,
},
_ => None,
}
}
}