123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- use crate::{
- connection::{Connection, ConnectionStatus},
- dispatcher,
- error::Error,
- value::Value,
- };
- use bytes::Bytes;
- use metered::{ErrorCount, HitCount, InFlight, ResponseTime, Throughput};
- use std::convert::TryInto;
- #[derive(Debug, Eq, PartialEq, Clone, Copy)]
- pub enum Flag {
-
- Write,
-
- ReadOnly,
-
- DenyOom,
-
- Admin,
-
- PubSub,
-
- NoScript,
-
- Random,
-
- SortForScript,
-
- Loading,
-
- Stale,
-
- SkipMonitor,
-
- SkipSlowlog,
-
- Fast,
-
- MayReplicate,
- }
- impl ToString for Flag {
- fn to_string(&self) -> String {
- match self {
- Self::Write => "write",
- Self::DenyOom => "denyoom",
- Self::ReadOnly => "readonly",
- Self::Admin => "admin",
- Self::PubSub => "pubsub",
- Self::NoScript => "noscript",
- Self::Random => "random",
- Self::SortForScript => "sort_for_script",
- Self::Loading => "loading",
- Self::Stale => "stale",
- Self::SkipMonitor => "skip_monitor",
- Self::SkipSlowlog => "skip_slowlog",
- Self::Fast => "fast",
- Self::MayReplicate => "may_replicate",
- }
- .to_owned()
- }
- }
- #[derive(Debug)]
- pub struct Command {
- name: &'static str,
- group: &'static str,
- flags: &'static [Flag],
- min_args: i32,
- key_start: i32,
- key_stop: i32,
- key_step: usize,
- is_queueable: bool,
- metrics: Metrics,
- }
- #[derive(Debug, Default, serde::Serialize)]
- pub struct Metrics {
-
- pub hit_count: HitCount,
-
- pub error_count: ErrorCount,
-
- pub in_flight: InFlight,
-
- pub response_time: ResponseTime,
-
- pub throughput: Throughput,
- }
- impl Command {
-
- pub fn new(
- name: &'static str,
- group: &'static str,
- flags: &'static [Flag],
- min_args: i32,
- key_start: i32,
- key_stop: i32,
- key_step: usize,
- is_queueable: bool,
- ) -> Self {
- Self {
- name,
- group,
- flags,
- min_args,
- key_start,
- key_stop,
- key_step,
- is_queueable,
- metrics: Metrics::default(),
- }
- }
-
- pub fn metrics(&self) -> &Metrics {
- &self.metrics
- }
-
- pub fn is_pubsub_executable(&self) -> bool {
- self.group == "pubsub" || self.name == "PING" || self.name == "RESET" || self.name == "QUIT"
- }
-
- pub fn is_queueable(&self) -> bool {
- self.is_queueable
- }
-
- pub fn get_keys<'a>(&self, args: &'a [Bytes]) -> Vec<&'a Bytes> {
- let start = self.key_start;
- let stop = if self.key_stop > 0 {
- self.key_stop
- } else {
- (args.len() as i32) + self.key_stop
- };
- if start == 0 {
- return vec![];
- }
- let mut result = vec![];
- for i in (start..stop + 1).step_by(self.key_step) {
- result.push(&args[i as usize]);
- }
- result
- }
-
- pub fn check_number_args(&self, n: usize) -> bool {
- if (self.min_args >= 0) {
- n == (self.min_args as i32).try_into().unwrap_or(0)
- } else {
- let s: usize = (self.min_args as i32).abs().try_into().unwrap_or(0);
- n >= s
- }
- }
-
-
- pub fn get_command_info(&self) -> Value {
- Value::Array(vec![
- self.name().into(),
- self.get_min_args().into(),
- Value::Array(
- self.get_flags()
- .iter()
- .map(|m| m.to_string().into())
- .collect(),
- ),
- self.get_key_start().into(),
- self.get_key_stop().into(),
- self.get_key_step().into(),
- ])
- }
-
- pub fn get_flags(&self) -> Vec<Flag> {
- self.flags.to_vec()
- }
-
-
- pub fn get_min_args(&self) -> i32 {
- self.min_args
- }
-
- pub fn get_key_start(&self) -> i32 {
- self.key_start
- }
-
- pub fn get_key_stop(&self) -> i32 {
- self.key_stop
- }
-
-
- pub fn get_key_step(&self) -> usize {
- self.key_step
- }
-
- pub fn group(&self) -> &'static str {
- &self.group
- }
-
- pub fn name(&self) -> &'static str {
- &self.name
- }
- }
|