// Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0

use redis::{Cmd, cmd};

#[cfg(feature = "proto")]
use crate::command_request::RequestType as ProtobufRequestType;

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub enum RequestType {
    /// Invalid request type
    InvalidRequest = 0,
    /// An unknown command, where all arguments are defined by the user.
    CustomCommand = 1,

    //// Bitmap commands
    BitCount = 101,
    BitField = 102,
    BitFieldReadOnly = 103,
    BitOp = 104,
    BitPos = 105,
    GetBit = 106,
    SetBit = 107,

    //// Cluster commands
    Asking = 201,
    ClusterAddSlots = 202,
    ClusterAddSlotsRange = 203,
    ClusterBumpEpoch = 204,
    ClusterCountFailureReports = 205,
    ClusterCountKeysInSlot = 206,
    ClusterDelSlots = 207,
    ClusterDelSlotsRange = 208,
    ClusterFailover = 209,
    ClusterFlushSlots = 210,
    ClusterForget = 211,
    ClusterGetKeysInSlot = 212,
    ClusterInfo = 213,
    ClusterKeySlot = 214,
    ClusterLinks = 215,
    ClusterMeet = 216,
    ClusterMyId = 217,
    ClusterMyShardId = 218,
    ClusterNodes = 219,
    ClusterReplicas = 220,
    ClusterReplicate = 221,
    ClusterReset = 222,
    ClusterSaveConfig = 223,
    ClusterSetConfigEpoch = 224,
    ClusterSetslot = 225,
    ClusterShards = 226,
    ClusterSlaves = 227,
    ClusterSlots = 228,
    ReadOnly = 229,
    ReadWrite = 230,

    //// Connection Management commands
    Auth = 301,
    ClientCaching = 302,
    ClientGetName = 303,
    ClientGetRedir = 304,
    ClientId = 305,
    ClientInfo = 306,
    ClientKillSimple = 307,
    ClientKill = 308,
    ClientList = 309,
    ClientNoEvict = 310,
    ClientNoTouch = 311,
    ClientPause = 312,
    ClientReply = 313,
    ClientSetInfo = 314,
    ClientSetName = 315,
    ClientTracking = 316,
    ClientTrackingInfo = 317,
    ClientUnblock = 318,
    ClientUnpause = 319,
    Echo = 320,
    Hello = 321,
    Ping = 322,
    Quit = 323, // deprecated in 7.2.0
    Reset = 324,
    Select = 325,

    //// Generic commands
    Copy = 401,
    Del = 402,
    Dump = 403,
    Exists = 404,
    Expire = 405,
    ExpireAt = 406,
    ExpireTime = 407,
    Keys = 408,
    Migrate = 409,
    Move = 410,
    ObjectEncoding = 411,
    ObjectFreq = 412,
    ObjectIdleTime = 413,
    ObjectRefCount = 414,
    Persist = 415,
    PExpire = 416,
    PExpireAt = 417,
    PExpireTime = 418,
    PTTL = 419,
    RandomKey = 420,
    Rename = 421,
    RenameNX = 422,
    Restore = 423,
    Scan = 424,
    Sort = 425,
    SortReadOnly = 426,
    Touch = 427,
    TTL = 428,
    Type = 429,
    Unlink = 430,
    Wait = 431,
    WaitAof = 432,

    //// Geospatial indices commands
    GeoAdd = 501,
    GeoDist = 502,
    GeoHash = 503,
    GeoPos = 504,
    GeoRadius = 505,
    GeoRadiusReadOnly = 506, // deprecated in 6.2.0
    GeoRadiusByMember = 507,
    GeoRadiusByMemberReadOnly = 508, // deprecated in 6.2.0
    GeoSearch = 509,
    GeoSearchStore = 510,

    //// Hash commands
    HDel = 601,
    HExists = 602,
    HGet = 603,
    HGetAll = 604,
    HIncrBy = 605,
    HIncrByFloat = 606,
    HKeys = 607,
    HLen = 608,
    HMGet = 609,
    HMSet = 610,
    HRandField = 611,
    HScan = 612,
    HSet = 613,
    HSetNX = 614,
    HStrlen = 615,
    HVals = 616,
    HSetEx = 617,
    HGetEx = 618,
    HExpire = 619,
    HExpireAt = 620,
    HPExpire = 621,
    HPExpireAt = 622,
    HPersist = 623,
    HTtl = 624,
    HPTtl = 625,
    HExpireTime = 626,
    HPExpireTime = 627,

    //// HyperLogLog commands
    PfAdd = 701,
    PfCount = 702,
    PfMerge = 703,

    //// List commands
    BLMove = 801,
    BLMPop = 802,
    BLPop = 803,
    BRPop = 804,
    BRPopLPush = 805, // deprecated in 6.2.0
    LIndex = 806,
    LInsert = 807,
    LLen = 808,
    LMove = 809,
    LMPop = 810,
    LPop = 811,
    LPos = 812,
    LPush = 813,
    LPushX = 814,
    LRange = 815,
    LRem = 816,
    LSet = 817,
    LTrim = 818,
    RPop = 819,
    RPopLPush = 820, // deprecated in 6.2.0
    RPush = 821,
    RPushX = 822,

    //// Pub/Sub commands
    PSubscribe = 901,
    Publish = 902,
    PubSubChannels = 903,
    PubSubNumPat = 904,
    PubSubNumSub = 905,
    PubSubShardChannels = 906,
    PubSubShardNumSub = 907,
    PUnsubscribe = 908,
    SPublish = 909,
    SSubscribe = 910,
    Subscribe = 911,
    SUnsubscribe = 912,
    Unsubscribe = 913,
    SubscribeBlocking = 914,
    UnsubscribeBlocking = 915,
    PSubscribeBlocking = 916,
    PUnsubscribeBlocking = 917,
    SSubscribeBlocking = 918,
    SUnsubscribeBlocking = 919,
    GetSubscriptions = 920,

    //// Scripting and Functions commands
    Eval = 1001,
    EvalReadOnly = 1002,
    EvalSha = 1003,
    EvalShaReadOnly = 1004,
    FCall = 1005,
    FCallReadOnly = 1006,
    FunctionDelete = 1007,
    FunctionDump = 1008,
    FunctionFlush = 1009,
    FunctionKill = 1010,
    FunctionList = 1011,
    FunctionLoad = 1012,
    FunctionRestore = 1013,
    FunctionStats = 1014,
    ScriptDebug = 1015,
    ScriptExists = 1016,
    ScriptFlush = 1017,
    ScriptKill = 1018,
    ScriptLoad = 1019,
    ScriptShow = 1020,

    //// Server management commands
    AclCat = 1101,
    AclDelUser = 1102,
    AclDryRun = 1103,
    AclGenPass = 1104,
    AclGetUser = 1105,
    AclList = 1106,
    AclLoad = 1107,
    AclLog = 1108,
    AclSave = 1109,
    AclSetUser = 1110,
    AclUsers = 1111,
    AclWhoami = 1112,
    BgRewriteAof = 1113,
    BgSave = 1114,
    Command_ = 1115, // Command - renamed to avoid collisions
    CommandCount = 1116,
    CommandDocs = 1117,
    CommandGetKeys = 1118,
    CommandGetKeysAndFlags = 1119,
    CommandInfo = 1120,
    CommandList = 1121,
    ConfigGet = 1122,
    ConfigResetStat = 1123,
    ConfigRewrite = 1124,
    ConfigSet = 1125,
    DBSize = 1126,
    FailOver = 1127,
    FlushAll = 1128,
    FlushDB = 1129,
    Info = 1130,
    LastSave = 1131,
    LatencyDoctor = 1132,
    LatencyGraph = 1133,
    LatencyHistogram = 1134,
    LatencyHistory = 1135,
    LatencyLatest = 1136,
    LatencyReset = 1137,
    Lolwut = 1138,
    MemoryDoctor = 1139,
    MemoryMallocStats = 1140,
    MemoryPurge = 1141,
    MemoryStats = 1142,
    MemoryUsage = 1143,
    ModuleList = 1144,
    ModuleLoad = 1145,
    ModuleLoadEx = 1146,
    ModuleUnload = 1147,
    Monitor = 1148,
    PSync = 1149,
    ReplConf = 1150,
    ReplicaOf = 1151,
    RestoreAsking = 1152,
    Role = 1153,
    Save = 1154,
    ShutDown = 1155,
    SlaveOf = 1156,
    SlowLogGet = 1157,
    SlowLogLen = 1158,
    SlowLogReset = 1159,
    SwapDb = 1160,
    Sync = 1161,
    Time = 1162,

    //// Set commands
    SAdd = 1201,
    SCard = 1202,
    SDiff = 1203,
    SDiffStore = 1204,
    SInter = 1205,
    SInterCard = 1206,
    SInterStore = 1207,
    SIsMember = 1208,
    SMembers = 1209,
    SMIsMember = 1210,
    SMove = 1211,
    SPop = 1212,
    SRandMember = 1213,
    SRem = 1214,
    SScan = 1215,
    SUnion = 1216,
    SUnionStore = 1217,

    //// Sorted set commands
    BZMPop = 1301,
    BZPopMax = 1302,
    BZPopMin = 1303,
    ZAdd = 1304,
    ZCard = 1305,
    ZCount = 1306,
    ZDiff = 1307,
    ZDiffStore = 1308,
    ZIncrBy = 1309,
    ZInter = 1310,
    ZInterCard = 1311,
    ZInterStore = 1312,
    ZLexCount = 1313,
    ZMPop = 1314,
    ZMScore = 1315,
    ZPopMax = 1316,
    ZPopMin = 1317,
    ZRandMember = 1318,
    ZRange = 1319,
    ZRangeByLex = 1320,
    ZRangeByScore = 1321,
    ZRangeStore = 1322,
    ZRank = 1323,
    ZRem = 1324,
    ZRemRangeByLex = 1325,
    ZRemRangeByRank = 1326,
    ZRemRangeByScore = 1327,
    ZRevRange = 1328,
    ZRevRangeByLex = 1329,
    ZRevRangeByScore = 1330,
    ZRevRank = 1331,
    ZScan = 1332,
    ZScore = 1333,
    ZUnion = 1334,
    ZUnionStore = 1335,

    //// Stream commands
    XAck = 1401,
    XAdd = 1402,
    XAutoClaim = 1403,
    XClaim = 1404,
    XDel = 1405,
    XGroupCreate = 1406,
    XGroupCreateConsumer = 1407,
    XGroupDelConsumer = 1408,
    XGroupDestroy = 1409,
    XGroupSetId = 1410,
    XInfoConsumers = 1411,
    XInfoGroups = 1412,
    XInfoStream = 1413,
    XLen = 1414,
    XPending = 1415,
    XRange = 1416,
    XRead = 1417,
    XReadGroup = 1418,
    XRevRange = 1419,
    XSetId = 1420,
    XTrim = 1421,

    //// String commands
    Append = 1501,
    Decr = 1502,
    DecrBy = 1503,
    Get = 1504,
    GetDel = 1505,
    GetEx = 1506,
    GetRange = 1507,
    GetSet = 1508, // deprecated in 6.2.0
    Incr = 1509,
    IncrBy = 1510,
    IncrByFloat = 1511,
    LCS = 1512,
    MGet = 1513,
    MSet = 1514,
    MSetNX = 1515,
    PSetEx = 1516, // deprecated in 2.6.12
    Set = 1517,
    SetEx = 1518, // deprecated in 2.6.12
    SetNX = 1519, // deprecated in 2.6.12
    SetRange = 1520,
    Strlen = 1521,
    Substr = 1522,

    //// Transaction commands
    Discard = 1601,
    Exec = 1602,
    Multi = 1603,
    UnWatch = 1604,
    Watch = 1605,

    //// JSON commands
    JsonArrAppend = 2001,
    JsonArrIndex = 2002,
    JsonArrInsert = 2003,
    JsonArrLen = 2004,
    JsonArrPop = 2005,
    JsonArrTrim = 2006,
    JsonClear = 2007,
    JsonDebug = 2008,
    JsonDel = 2009,
    JsonForget = 2010,
    JsonGet = 2011,
    JsonMGet = 2012,
    JsonNumIncrBy = 2013,
    JsonNumMultBy = 2014,
    JsonObjKeys = 2015,
    JsonObjLen = 2016,
    JsonResp = 2017,
    JsonSet = 2018,
    JsonStrAppend = 2019,
    JsonStrLen = 2020,
    JsonToggle = 2021,
    JsonType = 2022,

    //// Vector Search commands
    FtList = 2101,
    FtAggregate = 2102,
    FtAliasAdd = 2103,
    FtAliasDel = 2104,
    FtAliasList = 2105,
    FtAliasUpdate = 2106,
    FtCreate = 2107,
    FtDropIndex = 2108,
    FtExplain = 2109,
    FtExplainCli = 2110,
    FtInfo = 2111,
    FtProfile = 2112,
    FtSearch = 2113,
}

fn get_two_word_command(first: &str, second: &str) -> Cmd {
    let mut cmd = cmd(first);
    cmd.arg(second);
    cmd
}

#[cfg(feature = "proto")]
impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
    fn from(value: ::protobuf::EnumOrUnknown<ProtobufRequestType>) -> Self {
        match value.enum_value_or(ProtobufRequestType::InvalidRequest) {
            ProtobufRequestType::InvalidRequest => RequestType::InvalidRequest,
            ProtobufRequestType::CustomCommand => RequestType::CustomCommand,
            ProtobufRequestType::Get => RequestType::Get,
            ProtobufRequestType::Set => RequestType::Set,
            ProtobufRequestType::Ping => RequestType::Ping,
            ProtobufRequestType::Info => RequestType::Info,
            ProtobufRequestType::Del => RequestType::Del,
            ProtobufRequestType::Select => RequestType::Select,
            ProtobufRequestType::ConfigGet => RequestType::ConfigGet,
            ProtobufRequestType::ConfigSet => RequestType::ConfigSet,
            ProtobufRequestType::ConfigResetStat => RequestType::ConfigResetStat,
            ProtobufRequestType::ConfigRewrite => RequestType::ConfigRewrite,
            ProtobufRequestType::Auth => RequestType::Auth,
            ProtobufRequestType::ClientCaching => RequestType::ClientCaching,
            ProtobufRequestType::ClientGetName => RequestType::ClientGetName,
            ProtobufRequestType::ClientGetRedir => RequestType::ClientGetRedir,
            ProtobufRequestType::ClientId => RequestType::ClientId,
            ProtobufRequestType::ClientInfo => RequestType::ClientInfo,
            ProtobufRequestType::ClientKillSimple => RequestType::ClientKillSimple,
            ProtobufRequestType::ClientKill => RequestType::ClientKill,
            ProtobufRequestType::ClientList => RequestType::ClientList,
            ProtobufRequestType::ClientNoEvict => RequestType::ClientNoEvict,
            ProtobufRequestType::ClientNoTouch => RequestType::ClientNoTouch,
            ProtobufRequestType::ClientPause => RequestType::ClientPause,
            ProtobufRequestType::ClientReply => RequestType::ClientReply,
            ProtobufRequestType::ClientSetInfo => RequestType::ClientSetInfo,
            ProtobufRequestType::ClientSetName => RequestType::ClientSetName,
            ProtobufRequestType::ClientTracking => RequestType::ClientTracking,
            ProtobufRequestType::ClientTrackingInfo => RequestType::ClientTrackingInfo,
            ProtobufRequestType::ClientUnblock => RequestType::ClientUnblock,
            ProtobufRequestType::ClientUnpause => RequestType::ClientUnpause,
            ProtobufRequestType::Hello => RequestType::Hello,
            ProtobufRequestType::Quit => RequestType::Quit,
            ProtobufRequestType::Reset => RequestType::Reset,
            ProtobufRequestType::Expire => RequestType::Expire,
            ProtobufRequestType::HSet => RequestType::HSet,
            ProtobufRequestType::HGet => RequestType::HGet,
            ProtobufRequestType::HDel => RequestType::HDel,
            ProtobufRequestType::HExists => RequestType::HExists,
            ProtobufRequestType::MSet => RequestType::MSet,
            ProtobufRequestType::MGet => RequestType::MGet,
            ProtobufRequestType::Incr => RequestType::Incr,
            ProtobufRequestType::IncrBy => RequestType::IncrBy,
            ProtobufRequestType::IncrByFloat => RequestType::IncrByFloat,
            ProtobufRequestType::Decr => RequestType::Decr,
            ProtobufRequestType::DecrBy => RequestType::DecrBy,
            ProtobufRequestType::HGetAll => RequestType::HGetAll,
            ProtobufRequestType::HMSet => RequestType::HMSet,
            ProtobufRequestType::HMGet => RequestType::HMGet,
            ProtobufRequestType::HIncrBy => RequestType::HIncrBy,
            ProtobufRequestType::HIncrByFloat => RequestType::HIncrByFloat,
            ProtobufRequestType::LPush => RequestType::LPush,
            ProtobufRequestType::LPop => RequestType::LPop,
            ProtobufRequestType::RPush => RequestType::RPush,
            ProtobufRequestType::RPop => RequestType::RPop,
            ProtobufRequestType::LLen => RequestType::LLen,
            ProtobufRequestType::LRem => RequestType::LRem,
            ProtobufRequestType::LRange => RequestType::LRange,
            ProtobufRequestType::LTrim => RequestType::LTrim,
            ProtobufRequestType::SAdd => RequestType::SAdd,
            ProtobufRequestType::SRem => RequestType::SRem,
            ProtobufRequestType::SMembers => RequestType::SMembers,
            ProtobufRequestType::SCard => RequestType::SCard,
            ProtobufRequestType::PExpireAt => RequestType::PExpireAt,
            ProtobufRequestType::PExpire => RequestType::PExpire,
            ProtobufRequestType::ExpireAt => RequestType::ExpireAt,
            ProtobufRequestType::Exists => RequestType::Exists,
            ProtobufRequestType::Unlink => RequestType::Unlink,
            ProtobufRequestType::TTL => RequestType::TTL,
            ProtobufRequestType::ZAdd => RequestType::ZAdd,
            ProtobufRequestType::ZRem => RequestType::ZRem,
            ProtobufRequestType::ZRange => RequestType::ZRange,
            ProtobufRequestType::ZCard => RequestType::ZCard,
            ProtobufRequestType::ZCount => RequestType::ZCount,
            ProtobufRequestType::ZIncrBy => RequestType::ZIncrBy,
            ProtobufRequestType::ZScore => RequestType::ZScore,
            ProtobufRequestType::Type => RequestType::Type,
            ProtobufRequestType::HLen => RequestType::HLen,
            ProtobufRequestType::Echo => RequestType::Echo,
            ProtobufRequestType::ZPopMin => RequestType::ZPopMin,
            ProtobufRequestType::Strlen => RequestType::Strlen,
            ProtobufRequestType::LIndex => RequestType::LIndex,
            ProtobufRequestType::ZPopMax => RequestType::ZPopMax,
            ProtobufRequestType::XAck => RequestType::XAck,
            ProtobufRequestType::XAdd => RequestType::XAdd,
            ProtobufRequestType::XReadGroup => RequestType::XReadGroup,
            ProtobufRequestType::XRead => RequestType::XRead,
            ProtobufRequestType::XGroupCreate => RequestType::XGroupCreate,
            ProtobufRequestType::XGroupDestroy => RequestType::XGroupDestroy,
            ProtobufRequestType::XTrim => RequestType::XTrim,
            ProtobufRequestType::HSetNX => RequestType::HSetNX,
            ProtobufRequestType::SIsMember => RequestType::SIsMember,
            ProtobufRequestType::HVals => RequestType::HVals,
            ProtobufRequestType::HSetEx => RequestType::HSetEx,
            ProtobufRequestType::HGetEx => RequestType::HGetEx,
            ProtobufRequestType::HExpire => RequestType::HExpire,
            ProtobufRequestType::HExpireAt => RequestType::HExpireAt,
            ProtobufRequestType::HPExpire => RequestType::HPExpire,
            ProtobufRequestType::HPExpireAt => RequestType::HPExpireAt,
            ProtobufRequestType::HPersist => RequestType::HPersist,
            ProtobufRequestType::HTtl => RequestType::HTtl,
            ProtobufRequestType::HPTtl => RequestType::HPTtl,
            ProtobufRequestType::HExpireTime => RequestType::HExpireTime,
            ProtobufRequestType::HPExpireTime => RequestType::HPExpireTime,
            ProtobufRequestType::PTTL => RequestType::PTTL,
            ProtobufRequestType::ZRemRangeByRank => RequestType::ZRemRangeByRank,
            ProtobufRequestType::Persist => RequestType::Persist,
            ProtobufRequestType::ZRemRangeByScore => RequestType::ZRemRangeByScore,
            ProtobufRequestType::Time => RequestType::Time,
            ProtobufRequestType::ZRank => RequestType::ZRank,
            ProtobufRequestType::Rename => RequestType::Rename,
            ProtobufRequestType::DBSize => RequestType::DBSize,
            ProtobufRequestType::BRPop => RequestType::BRPop,
            ProtobufRequestType::HKeys => RequestType::HKeys,
            ProtobufRequestType::PfAdd => RequestType::PfAdd,
            ProtobufRequestType::PfCount => RequestType::PfCount,
            ProtobufRequestType::PfMerge => RequestType::PfMerge,
            ProtobufRequestType::RPushX => RequestType::RPushX,
            ProtobufRequestType::LPushX => RequestType::LPushX,
            ProtobufRequestType::BLPop => RequestType::BLPop,
            ProtobufRequestType::LInsert => RequestType::LInsert,
            ProtobufRequestType::SPop => RequestType::SPop,
            ProtobufRequestType::ZMScore => RequestType::ZMScore,
            ProtobufRequestType::ZDiff => RequestType::ZDiff,
            ProtobufRequestType::ZDiffStore => RequestType::ZDiffStore,
            ProtobufRequestType::SetRange => RequestType::SetRange,
            ProtobufRequestType::ZRemRangeByLex => RequestType::ZRemRangeByLex,
            ProtobufRequestType::ZLexCount => RequestType::ZLexCount,
            ProtobufRequestType::Append => RequestType::Append,
            ProtobufRequestType::SDiffStore => RequestType::SDiffStore,
            ProtobufRequestType::SInter => RequestType::SInter,
            ProtobufRequestType::SInterStore => RequestType::SInterStore,
            ProtobufRequestType::SUnionStore => RequestType::SUnionStore,
            ProtobufRequestType::ZRangeStore => RequestType::ZRangeStore,
            ProtobufRequestType::ZRangeByLex => RequestType::ZRangeByLex,
            ProtobufRequestType::ZRangeByScore => RequestType::ZRangeByScore,
            ProtobufRequestType::ZRevRange => RequestType::ZRevRange,
            ProtobufRequestType::ZRevRangeByLex => RequestType::ZRevRangeByLex,
            ProtobufRequestType::ZRevRangeByScore => RequestType::ZRevRangeByScore,
            ProtobufRequestType::GetRange => RequestType::GetRange,
            ProtobufRequestType::SMove => RequestType::SMove,
            ProtobufRequestType::SMIsMember => RequestType::SMIsMember,
            ProtobufRequestType::ZUnionStore => RequestType::ZUnionStore,
            ProtobufRequestType::LastSave => RequestType::LastSave,
            ProtobufRequestType::GeoAdd => RequestType::GeoAdd,
            ProtobufRequestType::GeoHash => RequestType::GeoHash,
            ProtobufRequestType::ObjectEncoding => RequestType::ObjectEncoding,
            ProtobufRequestType::ObjectFreq => RequestType::ObjectFreq,
            ProtobufRequestType::ObjectIdleTime => RequestType::ObjectIdleTime,
            ProtobufRequestType::GeoDist => RequestType::GeoDist,
            ProtobufRequestType::SDiff => RequestType::SDiff,
            ProtobufRequestType::ObjectRefCount => RequestType::ObjectRefCount,
            ProtobufRequestType::Lolwut => RequestType::Lolwut,
            ProtobufRequestType::GeoPos => RequestType::GeoPos,
            ProtobufRequestType::BZPopMax => RequestType::BZPopMax,
            ProtobufRequestType::RenameNX => RequestType::RenameNX,
            ProtobufRequestType::Touch => RequestType::Touch,
            ProtobufRequestType::ZRevRank => RequestType::ZRevRank,
            ProtobufRequestType::ZInterStore => RequestType::ZInterStore,
            ProtobufRequestType::HRandField => RequestType::HRandField,
            ProtobufRequestType::ZUnion => RequestType::ZUnion,
            ProtobufRequestType::BZPopMin => RequestType::BZPopMin,
            ProtobufRequestType::FlushAll => RequestType::FlushAll,
            ProtobufRequestType::ZRandMember => RequestType::ZRandMember,
            ProtobufRequestType::BitCount => RequestType::BitCount,
            ProtobufRequestType::BZMPop => RequestType::BZMPop,
            ProtobufRequestType::SetBit => RequestType::SetBit,
            ProtobufRequestType::LMPop => RequestType::LMPop,
            ProtobufRequestType::BLMPop => RequestType::BLMPop,
            ProtobufRequestType::ZInterCard => RequestType::ZInterCard,
            ProtobufRequestType::ZMPop => RequestType::ZMPop,
            ProtobufRequestType::GetBit => RequestType::GetBit,
            ProtobufRequestType::ZInter => RequestType::ZInter,
            ProtobufRequestType::FunctionLoad => RequestType::FunctionLoad,
            ProtobufRequestType::FunctionList => RequestType::FunctionList,
            ProtobufRequestType::FunctionDelete => RequestType::FunctionDelete,
            ProtobufRequestType::FunctionFlush => RequestType::FunctionFlush,
            ProtobufRequestType::FCall => RequestType::FCall,
            ProtobufRequestType::BitPos => RequestType::BitPos,
            ProtobufRequestType::BitOp => RequestType::BitOp,
            ProtobufRequestType::HStrlen => RequestType::HStrlen,
            ProtobufRequestType::ExpireTime => RequestType::ExpireTime,
            ProtobufRequestType::PExpireTime => RequestType::PExpireTime,
            ProtobufRequestType::XLen => RequestType::XLen,
            ProtobufRequestType::FunctionKill => RequestType::FunctionKill,
            ProtobufRequestType::FunctionStats => RequestType::FunctionStats,
            ProtobufRequestType::FCallReadOnly => RequestType::FCallReadOnly,
            ProtobufRequestType::FlushDB => RequestType::FlushDB,
            ProtobufRequestType::LSet => RequestType::LSet,
            ProtobufRequestType::XDel => RequestType::XDel,
            ProtobufRequestType::XRange => RequestType::XRange,
            ProtobufRequestType::LMove => RequestType::LMove,
            ProtobufRequestType::BLMove => RequestType::BLMove,
            ProtobufRequestType::GetDel => RequestType::GetDel,
            ProtobufRequestType::SRandMember => RequestType::SRandMember,
            ProtobufRequestType::BitField => RequestType::BitField,
            ProtobufRequestType::BitFieldReadOnly => RequestType::BitFieldReadOnly,
            ProtobufRequestType::Move => RequestType::Move,
            ProtobufRequestType::Keys => RequestType::Keys,
            ProtobufRequestType::Migrate => RequestType::Migrate,
            ProtobufRequestType::SInterCard => RequestType::SInterCard,
            ProtobufRequestType::Copy => RequestType::Copy,
            ProtobufRequestType::Sort => RequestType::Sort,
            ProtobufRequestType::XRevRange => RequestType::XRevRange,
            ProtobufRequestType::MSetNX => RequestType::MSetNX,
            ProtobufRequestType::LPos => RequestType::LPos,
            ProtobufRequestType::LCS => RequestType::LCS,
            ProtobufRequestType::GeoSearch => RequestType::GeoSearch,
            ProtobufRequestType::SUnion => RequestType::SUnion,
            ProtobufRequestType::Watch => RequestType::Watch,
            ProtobufRequestType::UnWatch => RequestType::UnWatch,
            ProtobufRequestType::Discard => RequestType::Discard,
            ProtobufRequestType::Exec => RequestType::Exec,
            ProtobufRequestType::Multi => RequestType::Multi,
            ProtobufRequestType::GeoSearchStore => RequestType::GeoSearchStore,
            ProtobufRequestType::Publish => RequestType::Publish,
            ProtobufRequestType::SPublish => RequestType::SPublish,
            ProtobufRequestType::XGroupCreateConsumer => RequestType::XGroupCreateConsumer,
            ProtobufRequestType::XGroupDelConsumer => RequestType::XGroupDelConsumer,
            ProtobufRequestType::RandomKey => RequestType::RandomKey,
            ProtobufRequestType::GetEx => RequestType::GetEx,
            ProtobufRequestType::Dump => RequestType::Dump,
            ProtobufRequestType::Restore => RequestType::Restore,
            ProtobufRequestType::SortReadOnly => RequestType::SortReadOnly,
            ProtobufRequestType::FunctionDump => RequestType::FunctionDump,
            ProtobufRequestType::FunctionRestore => RequestType::FunctionRestore,
            ProtobufRequestType::XPending => RequestType::XPending,
            ProtobufRequestType::XGroupSetId => RequestType::XGroupSetId,
            ProtobufRequestType::SScan => RequestType::SScan,
            ProtobufRequestType::ZScan => RequestType::ZScan,
            ProtobufRequestType::HScan => RequestType::HScan,
            ProtobufRequestType::XAutoClaim => RequestType::XAutoClaim,
            ProtobufRequestType::XInfoGroups => RequestType::XInfoGroups,
            ProtobufRequestType::XInfoConsumers => RequestType::XInfoConsumers,
            ProtobufRequestType::XInfoStream => RequestType::XInfoStream,
            ProtobufRequestType::Wait => RequestType::Wait,
            ProtobufRequestType::WaitAof => RequestType::WaitAof,
            ProtobufRequestType::XClaim => RequestType::XClaim,
            ProtobufRequestType::Scan => RequestType::Scan,
            ProtobufRequestType::PubSubChannels => RequestType::PubSubChannels,
            ProtobufRequestType::PubSubNumSub => RequestType::PubSubNumSub,
            ProtobufRequestType::PubSubNumPat => RequestType::PubSubNumPat,
            ProtobufRequestType::PubSubShardChannels => RequestType::PubSubShardChannels,
            ProtobufRequestType::PubSubShardNumSub => RequestType::PubSubShardNumSub,
            ProtobufRequestType::EvalReadOnly => RequestType::EvalReadOnly,
            ProtobufRequestType::EvalShaReadOnly => RequestType::EvalShaReadOnly,
            ProtobufRequestType::ScriptDebug => RequestType::ScriptDebug,
            ProtobufRequestType::ScriptExists => RequestType::ScriptExists,
            ProtobufRequestType::ScriptFlush => RequestType::ScriptFlush,
            ProtobufRequestType::ScriptKill => RequestType::ScriptKill,
            ProtobufRequestType::ScriptShow => RequestType::ScriptShow,
            ProtobufRequestType::JsonArrAppend => RequestType::JsonArrAppend,
            ProtobufRequestType::JsonArrIndex => RequestType::JsonArrIndex,
            ProtobufRequestType::JsonArrInsert => RequestType::JsonArrInsert,
            ProtobufRequestType::JsonArrLen => RequestType::JsonArrLen,
            ProtobufRequestType::JsonArrPop => RequestType::JsonArrPop,
            ProtobufRequestType::JsonArrTrim => RequestType::JsonArrTrim,
            ProtobufRequestType::JsonClear => RequestType::JsonClear,
            ProtobufRequestType::JsonDebug => RequestType::JsonDebug,
            ProtobufRequestType::JsonDel => RequestType::JsonDel,
            ProtobufRequestType::JsonForget => RequestType::JsonForget,
            ProtobufRequestType::JsonGet => RequestType::JsonGet,
            ProtobufRequestType::JsonMGet => RequestType::JsonMGet,
            ProtobufRequestType::JsonNumIncrBy => RequestType::JsonNumIncrBy,
            ProtobufRequestType::JsonNumMultBy => RequestType::JsonNumMultBy,
            ProtobufRequestType::JsonObjKeys => RequestType::JsonObjKeys,
            ProtobufRequestType::JsonObjLen => RequestType::JsonObjLen,
            ProtobufRequestType::JsonResp => RequestType::JsonResp,
            ProtobufRequestType::JsonSet => RequestType::JsonSet,
            ProtobufRequestType::JsonStrAppend => RequestType::JsonStrAppend,
            ProtobufRequestType::JsonStrLen => RequestType::JsonStrLen,
            ProtobufRequestType::JsonToggle => RequestType::JsonToggle,
            ProtobufRequestType::JsonType => RequestType::JsonType,
            ProtobufRequestType::FtList => RequestType::FtList,
            ProtobufRequestType::FtAggregate => RequestType::FtAggregate,
            ProtobufRequestType::FtAliasAdd => RequestType::FtAliasAdd,
            ProtobufRequestType::FtAliasDel => RequestType::FtAliasDel,
            ProtobufRequestType::FtAliasList => RequestType::FtAliasList,
            ProtobufRequestType::FtAliasUpdate => RequestType::FtAliasUpdate,
            ProtobufRequestType::FtCreate => RequestType::FtCreate,
            ProtobufRequestType::FtDropIndex => RequestType::FtDropIndex,
            ProtobufRequestType::FtExplain => RequestType::FtExplain,
            ProtobufRequestType::FtExplainCli => RequestType::FtExplainCli,
            ProtobufRequestType::FtInfo => RequestType::FtInfo,
            ProtobufRequestType::FtProfile => RequestType::FtProfile,
            ProtobufRequestType::FtSearch => RequestType::FtSearch,
            ProtobufRequestType::ModuleList => RequestType::ModuleList,
            ProtobufRequestType::ModuleLoad => RequestType::ModuleLoad,
            ProtobufRequestType::ModuleLoadEx => RequestType::ModuleLoadEx,
            ProtobufRequestType::ModuleUnload => RequestType::ModuleUnload,
            ProtobufRequestType::Asking => RequestType::Asking,
            ProtobufRequestType::ClusterAddSlots => RequestType::ClusterAddSlots,
            ProtobufRequestType::ClusterAddSlotsRange => RequestType::ClusterAddSlotsRange,
            ProtobufRequestType::ClusterBumpEpoch => RequestType::ClusterBumpEpoch,
            ProtobufRequestType::ClusterCountFailureReports => {
                RequestType::ClusterCountFailureReports
            }
            ProtobufRequestType::ClusterCountKeysInSlot => RequestType::ClusterCountKeysInSlot,
            ProtobufRequestType::ClusterDelSlots => RequestType::ClusterDelSlots,
            ProtobufRequestType::ClusterDelSlotsRange => RequestType::ClusterDelSlotsRange,
            ProtobufRequestType::ClusterFailover => RequestType::ClusterFailover,
            ProtobufRequestType::ClusterFlushSlots => RequestType::ClusterFlushSlots,
            ProtobufRequestType::ClusterForget => RequestType::ClusterForget,
            ProtobufRequestType::ClusterGetKeysInSlot => RequestType::ClusterGetKeysInSlot,
            ProtobufRequestType::ClusterInfo => RequestType::ClusterInfo,
            ProtobufRequestType::ClusterKeySlot => RequestType::ClusterKeySlot,
            ProtobufRequestType::ClusterLinks => RequestType::ClusterLinks,
            ProtobufRequestType::ClusterMeet => RequestType::ClusterMeet,
            ProtobufRequestType::ClusterMyId => RequestType::ClusterMyId,
            ProtobufRequestType::ClusterMyShardId => RequestType::ClusterMyShardId,
            ProtobufRequestType::ClusterNodes => RequestType::ClusterNodes,
            ProtobufRequestType::ClusterReplicas => RequestType::ClusterReplicas,
            ProtobufRequestType::ClusterReplicate => RequestType::ClusterReplicate,
            ProtobufRequestType::ClusterReset => RequestType::ClusterReset,
            ProtobufRequestType::ClusterSaveConfig => RequestType::ClusterSaveConfig,
            ProtobufRequestType::ClusterSetConfigEpoch => RequestType::ClusterSetConfigEpoch,
            ProtobufRequestType::ClusterSetslot => RequestType::ClusterSetslot,
            ProtobufRequestType::ClusterShards => RequestType::ClusterShards,
            ProtobufRequestType::ClusterSlaves => RequestType::ClusterSlaves,
            ProtobufRequestType::ClusterSlots => RequestType::ClusterSlots,
            ProtobufRequestType::ReadOnly => RequestType::ReadOnly,
            ProtobufRequestType::ReadWrite => RequestType::ReadWrite,
            ProtobufRequestType::AclCat => RequestType::AclCat,
            ProtobufRequestType::AclDelUser => RequestType::AclDelUser,
            ProtobufRequestType::AclDryRun => RequestType::AclDryRun,
            ProtobufRequestType::AclGenPass => RequestType::AclGenPass,
            ProtobufRequestType::AclGetUser => RequestType::AclGetUser,
            ProtobufRequestType::AclList => RequestType::AclList,
            ProtobufRequestType::AclLoad => RequestType::AclLoad,
            ProtobufRequestType::AclLog => RequestType::AclLog,
            ProtobufRequestType::AclSave => RequestType::AclSave,
            ProtobufRequestType::AclSetUser => RequestType::AclSetUser,
            ProtobufRequestType::AclUsers => RequestType::AclUsers,
            ProtobufRequestType::AclWhoami => RequestType::AclWhoami,
            ProtobufRequestType::BgRewriteAof => RequestType::BgRewriteAof,
            ProtobufRequestType::BgSave => RequestType::BgSave,
            ProtobufRequestType::Command_ => RequestType::Command_,
            ProtobufRequestType::CommandCount => RequestType::CommandCount,
            ProtobufRequestType::CommandDocs => RequestType::CommandDocs,
            ProtobufRequestType::CommandGetKeys => RequestType::CommandGetKeys,
            ProtobufRequestType::CommandGetKeysAndFlags => RequestType::CommandGetKeysAndFlags,
            ProtobufRequestType::CommandInfo => RequestType::CommandInfo,
            ProtobufRequestType::CommandList => RequestType::CommandList,
            ProtobufRequestType::LatencyDoctor => RequestType::LatencyDoctor,
            ProtobufRequestType::LatencyGraph => RequestType::LatencyGraph,
            ProtobufRequestType::LatencyHistogram => RequestType::LatencyHistogram,
            ProtobufRequestType::LatencyHistory => RequestType::LatencyHistory,
            ProtobufRequestType::LatencyLatest => RequestType::LatencyLatest,
            ProtobufRequestType::LatencyReset => RequestType::LatencyReset,
            ProtobufRequestType::MemoryDoctor => RequestType::MemoryDoctor,
            ProtobufRequestType::MemoryMallocStats => RequestType::MemoryMallocStats,
            ProtobufRequestType::MemoryPurge => RequestType::MemoryPurge,
            ProtobufRequestType::MemoryStats => RequestType::MemoryStats,
            ProtobufRequestType::MemoryUsage => RequestType::MemoryUsage,
            ProtobufRequestType::FailOver => RequestType::FailOver,
            ProtobufRequestType::Monitor => RequestType::Monitor,
            ProtobufRequestType::PSync => RequestType::PSync,
            ProtobufRequestType::ReplConf => RequestType::ReplConf,
            ProtobufRequestType::ReplicaOf => RequestType::ReplicaOf,
            ProtobufRequestType::RestoreAsking => RequestType::RestoreAsking,
            ProtobufRequestType::Role => RequestType::Role,
            ProtobufRequestType::Save => RequestType::Save,
            ProtobufRequestType::ShutDown => RequestType::ShutDown,
            ProtobufRequestType::SlaveOf => RequestType::SlaveOf,
            ProtobufRequestType::SlowLogGet => RequestType::SlowLogGet,
            ProtobufRequestType::SlowLogLen => RequestType::SlowLogLen,
            ProtobufRequestType::SlowLogReset => RequestType::SlowLogReset,
            ProtobufRequestType::SwapDb => RequestType::SwapDb,
            ProtobufRequestType::Sync => RequestType::Sync,
            ProtobufRequestType::PSubscribe => RequestType::PSubscribe,
            ProtobufRequestType::PUnsubscribe => RequestType::PUnsubscribe,
            ProtobufRequestType::SSubscribe => RequestType::SSubscribe,
            ProtobufRequestType::Subscribe => RequestType::Subscribe,
            ProtobufRequestType::SUnsubscribe => RequestType::SUnsubscribe,
            ProtobufRequestType::Unsubscribe => RequestType::Unsubscribe,
            ProtobufRequestType::SubscribeBlocking => RequestType::SubscribeBlocking,
            ProtobufRequestType::UnsubscribeBlocking => RequestType::UnsubscribeBlocking,
            ProtobufRequestType::PSubscribeBlocking => RequestType::PSubscribeBlocking,
            ProtobufRequestType::PUnsubscribeBlocking => RequestType::PUnsubscribeBlocking,
            ProtobufRequestType::SSubscribeBlocking => RequestType::SSubscribeBlocking,
            ProtobufRequestType::SUnsubscribeBlocking => RequestType::SUnsubscribeBlocking,
            ProtobufRequestType::GetSubscriptions => RequestType::GetSubscriptions,
            _ => todo!(),
        }
    }
}

impl RequestType {
    /// Returns the compression behavior for this request type.
    pub fn compression_behavior(self) -> crate::compression::CommandCompressionBehavior {
        use crate::compression::CommandCompressionBehavior;
        match self {
            RequestType::Set => CommandCompressionBehavior::CompressValues,
            RequestType::Get => CommandCompressionBehavior::DecompressValues,
            _ => CommandCompressionBehavior::NoCompression,
        }
    }

    /// Returns a `Cmd` set with the command name matching the request.
    pub fn get_command(&self) -> Option<Cmd> {
        match self {
            RequestType::InvalidRequest => None,
            RequestType::CustomCommand => Some(Cmd::new()),
            RequestType::Get => Some(cmd("GET")),
            RequestType::Set => Some(cmd("SET")),
            RequestType::Ping => Some(cmd("PING")),
            RequestType::Info => Some(cmd("INFO")),
            RequestType::Del => Some(cmd("DEL")),
            RequestType::Select => Some(cmd("SELECT")),
            RequestType::ConfigGet => Some(get_two_word_command("CONFIG", "GET")),
            RequestType::ConfigSet => Some(get_two_word_command("CONFIG", "SET")),
            RequestType::ConfigResetStat => Some(get_two_word_command("CONFIG", "RESETSTAT")),
            RequestType::ConfigRewrite => Some(get_two_word_command("CONFIG", "REWRITE")),
            RequestType::Auth => Some(cmd("AUTH")),
            RequestType::ClientCaching => Some(get_two_word_command("CLIENT", "CACHING")),
            RequestType::ClientGetName => Some(get_two_word_command("CLIENT", "GETNAME")),
            RequestType::ClientGetRedir => Some(get_two_word_command("CLIENT", "GETREDIR")),
            RequestType::ClientId => Some(get_two_word_command("CLIENT", "ID")),
            RequestType::ClientInfo => Some(get_two_word_command("CLIENT", "INFO")),
            RequestType::ClientKillSimple => Some(get_two_word_command("CLIENT", "KILL")),
            RequestType::ClientKill => Some(get_two_word_command("CLIENT", "KILL")),
            RequestType::ClientList => Some(get_two_word_command("CLIENT", "LIST")),
            RequestType::ClientNoEvict => Some(get_two_word_command("CLIENT", "NO-EVICT")),
            RequestType::ClientNoTouch => Some(get_two_word_command("CLIENT", "NO-TOUCH")),
            RequestType::ClientPause => Some(get_two_word_command("CLIENT", "PAUSE")),
            RequestType::ClientReply => Some(get_two_word_command("CLIENT", "REPLY")),
            RequestType::ClientSetInfo => Some(get_two_word_command("CLIENT", "SETINFO")),
            RequestType::ClientSetName => Some(get_two_word_command("CLIENT", "SETNAME")),
            RequestType::ClientTracking => Some(get_two_word_command("CLIENT", "TRACKING")),
            RequestType::ClientTrackingInfo => Some(get_two_word_command("CLIENT", "TRACKINGINFO")),
            RequestType::ClientUnblock => Some(get_two_word_command("CLIENT", "UNBLOCK")),
            RequestType::ClientUnpause => Some(get_two_word_command("CLIENT", "UNPAUSE")),
            RequestType::Hello => Some(cmd("HELLO")),
            RequestType::Quit => Some(cmd("QUIT")),
            RequestType::Reset => Some(cmd("RESET")),
            RequestType::Expire => Some(cmd("EXPIRE")),
            RequestType::HSet => Some(cmd("HSET")),
            RequestType::HGet => Some(cmd("HGET")),
            RequestType::HDel => Some(cmd("HDEL")),
            RequestType::HExists => Some(cmd("HEXISTS")),
            RequestType::MSet => Some(cmd("MSET")),
            RequestType::MGet => Some(cmd("MGET")),
            RequestType::Incr => Some(cmd("INCR")),
            RequestType::IncrBy => Some(cmd("INCRBY")),
            RequestType::IncrByFloat => Some(cmd("INCRBYFLOAT")),
            RequestType::Decr => Some(cmd("DECR")),
            RequestType::DecrBy => Some(cmd("DECRBY")),
            RequestType::HGetAll => Some(cmd("HGETALL")),
            RequestType::HMSet => Some(cmd("HMSET")),
            RequestType::HMGet => Some(cmd("HMGET")),
            RequestType::HIncrBy => Some(cmd("HINCRBY")),
            RequestType::HIncrByFloat => Some(cmd("HINCRBYFLOAT")),
            RequestType::LPush => Some(cmd("LPUSH")),
            RequestType::LPop => Some(cmd("LPOP")),
            RequestType::RPush => Some(cmd("RPUSH")),
            RequestType::RPop => Some(cmd("RPOP")),
            RequestType::LLen => Some(cmd("LLEN")),
            RequestType::LRem => Some(cmd("LREM")),
            RequestType::LRange => Some(cmd("LRANGE")),
            RequestType::LTrim => Some(cmd("LTRIM")),
            RequestType::SAdd => Some(cmd("SADD")),
            RequestType::SRem => Some(cmd("SREM")),
            RequestType::SMembers => Some(cmd("SMEMBERS")),
            RequestType::SCard => Some(cmd("SCARD")),
            RequestType::PExpireAt => Some(cmd("PEXPIREAT")),
            RequestType::PExpire => Some(cmd("PEXPIRE")),
            RequestType::ExpireAt => Some(cmd("EXPIREAT")),
            RequestType::Exists => Some(cmd("EXISTS")),
            RequestType::Unlink => Some(cmd("UNLINK")),
            RequestType::TTL => Some(cmd("TTL")),
            RequestType::ZAdd => Some(cmd("ZADD")),
            RequestType::ZRem => Some(cmd("ZREM")),
            RequestType::ZRange => Some(cmd("ZRANGE")),
            RequestType::ZCard => Some(cmd("ZCARD")),
            RequestType::ZCount => Some(cmd("ZCOUNT")),
            RequestType::ZIncrBy => Some(cmd("ZINCRBY")),
            RequestType::ZScore => Some(cmd("ZSCORE")),
            RequestType::Type => Some(cmd("TYPE")),
            RequestType::HLen => Some(cmd("HLEN")),
            RequestType::Echo => Some(cmd("ECHO")),
            RequestType::ZPopMin => Some(cmd("ZPOPMIN")),
            RequestType::Strlen => Some(cmd("STRLEN")),
            RequestType::LIndex => Some(cmd("LINDEX")),
            RequestType::ZPopMax => Some(cmd("ZPOPMAX")),
            RequestType::XAck => Some(cmd("XACK")),
            RequestType::XAdd => Some(cmd("XADD")),
            RequestType::XReadGroup => Some(cmd("XREADGROUP")),
            RequestType::XRead => Some(cmd("XREAD")),
            RequestType::XGroupCreate => Some(get_two_word_command("XGROUP", "CREATE")),
            RequestType::XGroupDestroy => Some(get_two_word_command("XGROUP", "DESTROY")),
            RequestType::XTrim => Some(cmd("XTRIM")),
            RequestType::HSetNX => Some(cmd("HSETNX")),
            RequestType::SIsMember => Some(cmd("SISMEMBER")),
            RequestType::HVals => Some(cmd("HVALS")),
            RequestType::HSetEx => Some(cmd("HSETEX")),
            RequestType::HGetEx => Some(cmd("HGETEX")),
            RequestType::HExpire => Some(cmd("HEXPIRE")),
            RequestType::HExpireAt => Some(cmd("HEXPIREAT")),
            RequestType::HPExpire => Some(cmd("HPEXPIRE")),
            RequestType::HPExpireAt => Some(cmd("HPEXPIREAT")),
            RequestType::HPersist => Some(cmd("HPERSIST")),
            RequestType::HTtl => Some(cmd("HTTL")),
            RequestType::HPTtl => Some(cmd("HPTTL")),
            RequestType::HExpireTime => Some(cmd("HEXPIRETIME")),
            RequestType::HPExpireTime => Some(cmd("HPEXPIRETIME")),
            RequestType::PTTL => Some(cmd("PTTL")),
            RequestType::ZRemRangeByRank => Some(cmd("ZREMRANGEBYRANK")),
            RequestType::Persist => Some(cmd("PERSIST")),
            RequestType::ZRemRangeByScore => Some(cmd("ZREMRANGEBYSCORE")),
            RequestType::Time => Some(cmd("TIME")),
            RequestType::ZRank => Some(cmd("ZRANK")),
            RequestType::Rename => Some(cmd("RENAME")),
            RequestType::Keys => Some(cmd("KEYS")),
            RequestType::Migrate => Some(cmd("MIGRATE")),
            RequestType::DBSize => Some(cmd("DBSIZE")),
            RequestType::BgRewriteAof => Some(cmd("BGREWRITEAOF")),
            RequestType::BgSave => Some(cmd("BGSAVE")),
            RequestType::FailOver => Some(cmd("FAILOVER")),
            RequestType::BRPop => Some(cmd("BRPOP")),
            RequestType::HKeys => Some(cmd("HKEYS")),
            RequestType::PfAdd => Some(cmd("PFADD")),
            RequestType::PfCount => Some(cmd("PFCOUNT")),
            RequestType::PfMerge => Some(cmd("PFMERGE")),
            RequestType::RPushX => Some(cmd("RPUSHX")),
            RequestType::LPushX => Some(cmd("LPUSHX")),
            RequestType::BLPop => Some(cmd("BLPOP")),
            RequestType::LInsert => Some(cmd("LINSERT")),
            RequestType::SPop => Some(cmd("SPOP")),
            RequestType::ZMScore => Some(cmd("ZMSCORE")),
            RequestType::ZDiff => Some(cmd("ZDIFF")),
            RequestType::ZDiffStore => Some(cmd("ZDIFFSTORE")),
            RequestType::SetRange => Some(cmd("SETRANGE")),
            RequestType::ZRemRangeByLex => Some(cmd("ZREMRANGEBYLEX")),
            RequestType::ZLexCount => Some(cmd("ZLEXCOUNT")),
            RequestType::Append => Some(cmd("APPEND")),
            RequestType::SDiffStore => Some(cmd("SDIFFSTORE")),
            RequestType::SInter => Some(cmd("SINTER")),
            RequestType::SInterStore => Some(cmd("SINTERSTORE")),
            RequestType::SUnionStore => Some(cmd("SUNIONSTORE")),
            RequestType::ZRangeStore => Some(cmd("ZRANGESTORE")),
            RequestType::ZRangeByLex => Some(cmd("ZRANGEBYLEX")),
            RequestType::ZRangeByScore => Some(cmd("ZRANGEBYSCORE")),
            RequestType::ZRevRange => Some(cmd("ZREVRANGE")),
            RequestType::ZRevRangeByLex => Some(cmd("ZREVRANGEBYLEX")),
            RequestType::ZRevRangeByScore => Some(cmd("ZREVRANGEBYSCORE")),
            RequestType::GetRange => Some(cmd("GETRANGE")),
            RequestType::SMove => Some(cmd("SMOVE")),
            RequestType::SMIsMember => Some(cmd("SMISMEMBER")),
            RequestType::ZUnionStore => Some(cmd("ZUNIONSTORE")),
            RequestType::LastSave => Some(cmd("LASTSAVE")),
            RequestType::Monitor => Some(cmd("MONITOR")),
            RequestType::GeoAdd => Some(cmd("GEOADD")),
            RequestType::GeoHash => Some(cmd("GEOHASH")),
            RequestType::ObjectEncoding => Some(get_two_word_command("OBJECT", "ENCODING")),
            RequestType::ObjectFreq => Some(get_two_word_command("OBJECT", "FREQ")),
            RequestType::ObjectIdleTime => Some(get_two_word_command("OBJECT", "IDLETIME")),
            RequestType::GeoDist => Some(cmd("GEODIST")),
            RequestType::SDiff => Some(cmd("SDIFF")),
            RequestType::ObjectRefCount => Some(get_two_word_command("OBJECT", "REFCOUNT")),
            RequestType::Lolwut => Some(cmd("LOLWUT")),
            RequestType::GeoPos => Some(cmd("GEOPOS")),
            RequestType::BZPopMax => Some(cmd("BZPOPMAX")),
            RequestType::RenameNX => Some(cmd("RENAMENX")),
            RequestType::Touch => Some(cmd("TOUCH")),
            RequestType::ZRevRank => Some(cmd("ZREVRANK")),
            RequestType::ZInterStore => Some(cmd("ZINTERSTORE")),
            RequestType::HRandField => Some(cmd("HRANDFIELD")),
            RequestType::ZUnion => Some(cmd("ZUNION")),
            RequestType::BZPopMin => Some(cmd("BZPOPMIN")),
            RequestType::FlushAll => Some(cmd("FLUSHALL")),
            RequestType::PSync => Some(cmd("PSYNC")),
            RequestType::ReplConf => Some(cmd("REPLCONF")),
            RequestType::ReplicaOf => Some(cmd("REPLICAOF")),
            RequestType::RestoreAsking => Some(cmd("RESTORE-ASKING")),
            RequestType::Role => Some(cmd("ROLE")),
            RequestType::Save => Some(cmd("SAVE")),
            RequestType::ShutDown => Some(cmd("SHUTDOWN")),
            RequestType::SlaveOf => Some(cmd("SLAVEOF")),
            RequestType::SlowLogGet => Some(get_two_word_command("SLOWLOG", "GET")),
            RequestType::SlowLogLen => Some(get_two_word_command("SLOWLOG", "LEN")),
            RequestType::SlowLogReset => Some(get_two_word_command("SLOWLOG", "RESET")),
            RequestType::SwapDb => Some(cmd("SWAPDB")),
            RequestType::Sync => Some(cmd("SYNC")),
            RequestType::ZRandMember => Some(cmd("ZRANDMEMBER")),
            RequestType::BitCount => Some(cmd("BITCOUNT")),
            RequestType::BZMPop => Some(cmd("BZMPOP")),
            RequestType::LMPop => Some(cmd("LMPOP")),
            RequestType::BLMPop => Some(cmd("BLMPOP")),
            RequestType::SetBit => Some(cmd("SETBIT")),
            RequestType::ZInterCard => Some(cmd("ZINTERCARD")),
            RequestType::ZMPop => Some(cmd("ZMPOP")),
            RequestType::GetBit => Some(cmd("GETBIT")),
            RequestType::ZInter => Some(cmd("ZINTER")),
            RequestType::FunctionLoad => Some(get_two_word_command("FUNCTION", "LOAD")),
            RequestType::FunctionList => Some(get_two_word_command("FUNCTION", "LIST")),
            RequestType::FunctionDelete => Some(get_two_word_command("FUNCTION", "DELETE")),
            RequestType::FunctionFlush => Some(get_two_word_command("FUNCTION", "FLUSH")),
            RequestType::FCall => Some(cmd("FCALL")),
            RequestType::BitPos => Some(cmd("BITPOS")),
            RequestType::BitOp => Some(cmd("BITOP")),
            RequestType::HStrlen => Some(cmd("HSTRLEN")),
            RequestType::ExpireTime => Some(cmd("EXPIRETIME")),
            RequestType::PExpireTime => Some(cmd("PEXPIRETIME")),
            RequestType::XLen => Some(cmd("XLEN")),
            RequestType::FunctionKill => Some(get_two_word_command("FUNCTION", "KILL")),
            RequestType::FunctionStats => Some(get_two_word_command("FUNCTION", "STATS")),
            RequestType::FCallReadOnly => Some(cmd("FCALL_RO")),
            RequestType::FlushDB => Some(cmd("FLUSHDB")),
            RequestType::LSet => Some(cmd("LSET")),
            RequestType::XDel => Some(cmd("XDEL")),
            RequestType::XRange => Some(cmd("XRANGE")),
            RequestType::LMove => Some(cmd("LMOVE")),
            RequestType::BLMove => Some(cmd("BLMOVE")),
            RequestType::GetDel => Some(cmd("GETDEL")),
            RequestType::SRandMember => Some(cmd("SRANDMEMBER")),
            RequestType::BitField => Some(cmd("BITFIELD")),
            RequestType::BitFieldReadOnly => Some(cmd("BITFIELD_RO")),
            RequestType::Move => Some(cmd("MOVE")),
            RequestType::SInterCard => Some(cmd("SINTERCARD")),
            RequestType::Copy => Some(cmd("COPY")),
            RequestType::Sort => Some(cmd("SORT")),
            RequestType::XRevRange => Some(cmd("XREVRANGE")),
            RequestType::MSetNX => Some(cmd("MSETNX")),
            RequestType::LPos => Some(cmd("LPOS")),
            RequestType::LCS => Some(cmd("LCS")),
            RequestType::GeoSearch => Some(cmd("GEOSEARCH")),
            RequestType::SUnion => Some(cmd("SUNION")),
            RequestType::Watch => Some(cmd("WATCH")),
            RequestType::UnWatch => Some(cmd("UNWATCH")),
            RequestType::Discard => Some(cmd("DISCARD")),
            RequestType::Exec => Some(cmd("EXEC")),
            RequestType::Multi => Some(cmd("MULTI")),
            RequestType::GeoSearchStore => Some(cmd("GEOSEARCHSTORE")),
            RequestType::Publish => Some(cmd("PUBLISH")),
            RequestType::SPublish => Some(cmd("SPUBLISH")),
            RequestType::XGroupCreateConsumer => {
                Some(get_two_word_command("XGROUP", "CREATECONSUMER"))
            }
            RequestType::XGroupDelConsumer => Some(get_two_word_command("XGROUP", "DELCONSUMER")),
            RequestType::RandomKey => Some(cmd("RANDOMKEY")),
            RequestType::GetEx => Some(cmd("GETEX")),
            RequestType::Dump => Some(cmd("DUMP")),
            RequestType::Restore => Some(cmd("RESTORE")),
            RequestType::SortReadOnly => Some(cmd("SORT_RO")),
            RequestType::FunctionDump => Some(get_two_word_command("FUNCTION", "DUMP")),
            RequestType::FunctionRestore => Some(get_two_word_command("FUNCTION", "RESTORE")),
            RequestType::XPending => Some(cmd("XPENDING")),
            RequestType::XGroupSetId => Some(get_two_word_command("XGROUP", "SETID")),
            RequestType::SScan => Some(cmd("SSCAN")),
            RequestType::ZScan => Some(cmd("ZSCAN")),
            RequestType::HScan => Some(cmd("HSCAN")),
            RequestType::XAutoClaim => Some(cmd("XAUTOCLAIM")),
            RequestType::XInfoGroups => Some(get_two_word_command("XINFO", "GROUPS")),
            RequestType::XInfoConsumers => Some(get_two_word_command("XINFO", "CONSUMERS")),
            RequestType::XInfoStream => Some(get_two_word_command("XINFO", "STREAM")),
            RequestType::Wait => Some(cmd("WAIT")),
            RequestType::WaitAof => Some(cmd("WAITAOF")),
            RequestType::XClaim => Some(cmd("XCLAIM")),
            RequestType::Scan => Some(cmd("SCAN")),
            RequestType::PubSubChannels => Some(get_two_word_command("PUBSUB", "CHANNELS")),
            RequestType::PubSubNumSub => Some(get_two_word_command("PUBSUB", "NUMSUB")),
            RequestType::PubSubNumPat => Some(get_two_word_command("PUBSUB", "NUMPAT")),
            RequestType::PubSubShardChannels => {
                Some(get_two_word_command("PUBSUB", "SHARDCHANNELS"))
            }
            RequestType::PubSubShardNumSub => Some(get_two_word_command("PUBSUB", "SHARDNUMSUB")),
            RequestType::EvalReadOnly => Some(cmd("EVAL_RO")),
            RequestType::EvalShaReadOnly => Some(cmd("EVALSHA_RO")),
            RequestType::ScriptDebug => Some(get_two_word_command("SCRIPT", "DEBUG")),
            RequestType::ScriptExists => Some(get_two_word_command("SCRIPT", "EXISTS")),
            RequestType::ScriptFlush => Some(get_two_word_command("SCRIPT", "FLUSH")),
            RequestType::ScriptKill => Some(get_two_word_command("SCRIPT", "KILL")),
            RequestType::ScriptShow => Some(get_two_word_command("SCRIPT", "SHOW")),
            RequestType::JsonArrAppend => Some(cmd("JSON.ARRAPPEND")),
            RequestType::JsonArrIndex => Some(cmd("JSON.ARRINDEX")),
            RequestType::JsonArrInsert => Some(cmd("JSON.ARRINSERT")),
            RequestType::JsonArrLen => Some(cmd("JSON.ARRLEN")),
            RequestType::JsonArrPop => Some(cmd("JSON.ARRPOP")),
            RequestType::JsonArrTrim => Some(cmd("JSON.ARRTRIM")),
            RequestType::JsonClear => Some(cmd("JSON.CLEAR")),
            RequestType::JsonDebug => Some(cmd("JSON.DEBUG")),
            RequestType::JsonDel => Some(cmd("JSON.DEL")),
            RequestType::JsonForget => Some(cmd("JSON.FORGET")),
            RequestType::JsonGet => Some(cmd("JSON.GET")),
            RequestType::JsonMGet => Some(cmd("JSON.MGET")),
            RequestType::JsonNumIncrBy => Some(cmd("JSON.NUMINCRBY")),
            RequestType::JsonNumMultBy => Some(cmd("JSON.NUMMULTBY")),
            RequestType::JsonObjKeys => Some(cmd("JSON.OBJKEYS")),
            RequestType::JsonObjLen => Some(cmd("JSON.OBJLEN")),
            RequestType::JsonResp => Some(cmd("JSON.RESP")),
            RequestType::JsonSet => Some(cmd("JSON.SET")),
            RequestType::JsonStrAppend => Some(cmd("JSON.STRAPPEND")),
            RequestType::JsonStrLen => Some(cmd("JSON.STRLEN")),
            RequestType::JsonToggle => Some(cmd("JSON.TOGGLE")),
            RequestType::JsonType => Some(cmd("JSON.TYPE")),
            RequestType::FtList => Some(cmd("FT._LIST")),
            RequestType::FtAggregate => Some(cmd("FT.AGGREGATE")),
            RequestType::FtAliasAdd => Some(cmd("FT.ALIASADD")),
            RequestType::FtAliasDel => Some(cmd("FT.ALIASDEL")),
            RequestType::FtAliasList => Some(cmd("FT._ALIASLIST")),
            RequestType::FtAliasUpdate => Some(cmd("FT.ALIASUPDATE")),
            RequestType::FtCreate => Some(cmd("FT.CREATE")),
            RequestType::FtDropIndex => Some(cmd("FT.DROPINDEX")),
            RequestType::FtExplain => Some(cmd("FT.EXPLAIN")),
            RequestType::FtExplainCli => Some(cmd("FT.EXPLAINCLI")),
            RequestType::FtInfo => Some(cmd("FT.INFO")),
            RequestType::FtProfile => Some(cmd("FT.PROFILE")),
            RequestType::FtSearch => Some(cmd("FT.SEARCH")),
            RequestType::ModuleList => Some(get_two_word_command("MODULE", "LIST")),
            RequestType::ModuleLoad => Some(get_two_word_command("MODULE", "LOAD")),
            RequestType::ModuleLoadEx => Some(get_two_word_command("MODULE", "LOADEX")),
            RequestType::ModuleUnload => Some(get_two_word_command("MODULE", "UNLOAD")),
            RequestType::Asking => Some(cmd("ASKING")),
            RequestType::ClusterAddSlots => Some(get_two_word_command("CLUSTER", "ADDSLOTS")),
            RequestType::ClusterAddSlotsRange => {
                Some(get_two_word_command("CLUSTER", "ADDSLOTSRANGE"))
            }
            RequestType::ClusterBumpEpoch => Some(get_two_word_command("CLUSTER", "BUMPEPOCH")),
            RequestType::ClusterCountFailureReports => {
                Some(get_two_word_command("CLUSTER", "COUNT-FAILURE-REPORTS"))
            }
            RequestType::ClusterCountKeysInSlot => {
                Some(get_two_word_command("CLUSTER", "COUNTKEYSINSLOT"))
            }
            RequestType::ClusterDelSlots => Some(get_two_word_command("CLUSTER", "DELSLOTS")),
            RequestType::ClusterDelSlotsRange => {
                Some(get_two_word_command("CLUSTER", "DELSLOTSRANGE"))
            }
            RequestType::ClusterFailover => Some(get_two_word_command("CLUSTER", "FAILOVER")),
            RequestType::ClusterFlushSlots => Some(get_two_word_command("CLUSTER", "FLUSHSLOTS")),
            RequestType::ClusterForget => Some(get_two_word_command("CLUSTER", "FORGET")),
            RequestType::ClusterGetKeysInSlot => {
                Some(get_two_word_command("CLUSTER", "GETKEYSINSLOT"))
            }
            RequestType::ClusterInfo => Some(get_two_word_command("CLUSTER", "INFO")),
            RequestType::ClusterKeySlot => Some(get_two_word_command("CLUSTER", "KEYSLOT")),
            RequestType::ClusterLinks => Some(get_two_word_command("CLUSTER", "LINKS")),
            RequestType::ClusterMeet => Some(get_two_word_command("CLUSTER", "MEET")),
            RequestType::ClusterMyId => Some(get_two_word_command("CLUSTER", "MYID")),
            RequestType::ClusterMyShardId => Some(get_two_word_command("CLUSTER", "MYSHARDID")),
            RequestType::ClusterNodes => Some(get_two_word_command("CLUSTER", "NODES")),
            RequestType::ClusterReplicas => Some(get_two_word_command("CLUSTER", "REPLICAS")),
            RequestType::ClusterReplicate => Some(get_two_word_command("CLUSTER", "REPLICATE")),
            RequestType::ClusterReset => Some(get_two_word_command("CLUSTER", "RESET")),
            RequestType::ClusterSaveConfig => Some(get_two_word_command("CLUSTER", "SAVECONFIG")),
            RequestType::ClusterSetConfigEpoch => {
                Some(get_two_word_command("CLUSTER", "SET-CONFIG-EPOCH"))
            }
            RequestType::ClusterSetslot => Some(get_two_word_command("CLUSTER", "SETSLOT")),
            RequestType::ClusterShards => Some(get_two_word_command("CLUSTER", "SHARDS")),
            RequestType::ClusterSlaves => Some(get_two_word_command("CLUSTER", "SLAVES")),
            RequestType::ClusterSlots => Some(get_two_word_command("CLUSTER", "SLOTS")),
            RequestType::ReadOnly => Some(cmd("READONLY")),
            RequestType::ReadWrite => Some(cmd("READWRITE")),
            RequestType::AclCat => Some(get_two_word_command("ACL", "CAT")),
            RequestType::AclDelUser => Some(get_two_word_command("ACL", "DELUSER")),
            RequestType::AclDryRun => Some(get_two_word_command("ACL", "DRYRUN")),
            RequestType::AclGenPass => Some(get_two_word_command("ACL", "GENPASS")),
            RequestType::AclGetUser => Some(get_two_word_command("ACL", "GETUSER")),
            RequestType::AclList => Some(get_two_word_command("ACL", "LIST")),
            RequestType::AclLoad => Some(get_two_word_command("ACL", "LOAD")),
            RequestType::AclLog => Some(get_two_word_command("ACL", "LOG")),
            RequestType::AclSave => Some(get_two_word_command("ACL", "SAVE")),
            RequestType::AclSetUser => Some(get_two_word_command("ACL", "SETUSER")),
            RequestType::AclUsers => Some(get_two_word_command("ACL", "USERS")),
            RequestType::AclWhoami => Some(get_two_word_command("ACL", "WHOAMI")),
            RequestType::Command_ => Some(cmd("COMMAND")),
            RequestType::CommandCount => Some(get_two_word_command("COMMAND", "COUNT")),
            RequestType::CommandDocs => Some(get_two_word_command("COMMAND", "DOCS")),
            RequestType::CommandGetKeys => Some(get_two_word_command("COMMAND", "GETKEYS")),
            RequestType::CommandGetKeysAndFlags => {
                Some(get_two_word_command("COMMAND", "GETKEYSANDFLAGS"))
            }
            RequestType::CommandInfo => Some(get_two_word_command("COMMAND", "INFO")),
            RequestType::CommandList => Some(get_two_word_command("COMMAND", "LIST")),
            RequestType::LatencyDoctor => Some(get_two_word_command("LATENCY", "DOCTOR")),
            RequestType::LatencyGraph => Some(get_two_word_command("LATENCY", "GRAPH")),
            RequestType::LatencyHistogram => Some(get_two_word_command("LATENCY", "HISTOGRAM")),
            RequestType::LatencyHistory => Some(get_two_word_command("LATENCY", "HISTORY")),
            RequestType::LatencyLatest => Some(get_two_word_command("LATENCY", "LATEST")),
            RequestType::LatencyReset => Some(get_two_word_command("LATENCY", "RESET")),
            RequestType::MemoryDoctor => Some(get_two_word_command("MEMORY", "DOCTOR")),
            RequestType::MemoryMallocStats => Some(get_two_word_command("MEMORY", "MALLOC-STATS")),
            RequestType::MemoryPurge => Some(get_two_word_command("MEMORY", "PURGE")),
            RequestType::MemoryStats => Some(get_two_word_command("MEMORY", "STATS")),
            RequestType::MemoryUsage => Some(get_two_word_command("MEMORY", "USAGE")),
            RequestType::PSubscribe => Some(cmd("PSUBSCRIBE")),
            RequestType::PUnsubscribe => Some(cmd("PUNSUBSCRIBE")),
            RequestType::SSubscribe => Some(cmd("SSUBSCRIBE")),
            RequestType::Subscribe => Some(cmd("SUBSCRIBE")),
            RequestType::SUnsubscribe => Some(cmd("SUNSUBSCRIBE")),
            RequestType::Unsubscribe => Some(cmd("UNSUBSCRIBE")),
            RequestType::SubscribeBlocking => Some(cmd("SUBSCRIBE_BLOCKING")),
            RequestType::UnsubscribeBlocking => Some(cmd("UNSUBSCRIBE_BLOCKING")),
            RequestType::PSubscribeBlocking => Some(cmd("PSUBSCRIBE_BLOCKING")),
            RequestType::PUnsubscribeBlocking => Some(cmd("PUNSUBSCRIBE_BLOCKING")),
            RequestType::SSubscribeBlocking => Some(cmd("SSUBSCRIBE_BLOCKING")),
            RequestType::SUnsubscribeBlocking => Some(cmd("SUNSUBSCRIBE_BLOCKING")),
            RequestType::GetSubscriptions => Some(cmd("GET_SUBSCRIPTIONS")),
            _ => todo!(),
        }
    }
}
