redis_imitate/commands/
parser.rs

1//! # Command Parser Module
2//! 
3//! Provides parsing functionality for Redis-like commands, converting string input
4//! into structured command enums. Supports basic key-value operations, list operations,
5//! and transaction commands.
6
7/// Represents all supported Redis-like commands
8
9#[derive(Debug,PartialEq,Clone)]
10pub enum Command {
11    Set(String, String),
12    Get(String),
13    Del(String),
14    Incr(String),
15    Decr(String),
16    LPush(String, String),
17    RPush(String, String),
18    LPop(String),
19    RPop(String),
20    LLen(String),
21    Multi,
22    Exec,
23    Discard,
24    Unknown(String),
25}
26
27/// Parser for Redis-like commands
28///
29/// Converts string input into structured Command enums, handling command validation
30/// and argument parsing.
31pub struct CommandParser;
32
33impl CommandParser {
34    /// Parses a command string into a Command enum
35    ///
36    /// # Arguments
37    ///
38    /// * `input` - The command string to parse
39    ///
40    /// # Returns
41    ///
42    /// A Command enum variant representing the parsed command
43    ///
44    /// # Command Format
45    ///
46    /// * SET key value
47    /// * GET key
48    /// * DEL key
49    /// * INCR key
50    /// * DECR key
51    /// * LPUSH key value
52    /// * RPUSH key value
53    /// * LPOP key
54    /// * RPOP key
55    /// * LLEN key
56    /// * MULTI
57    /// * EXEC
58    /// * DISCARD
59    pub fn parse(input: &str) -> Command {
60        let parts: Vec<&str> = input.trim().split_whitespace().collect();
61        match parts.as_slice() {
62            [command, rest @ ..] => match command.to_uppercase().as_str() {
63                "SET" if rest.len() == 2 => Command::Set(rest[0].to_lowercase(), rest[1].to_string()),
64                "GET" if rest.len() == 1 => Command::Get(rest[0].to_lowercase()),
65                "DEL" if rest.len() == 1 => Command::Del(rest[0].to_lowercase()),
66                "INCR" if rest.len() == 1 => Command::Incr(rest[0].to_lowercase()),
67                "DECR" if rest.len() == 1 => Command::Decr(rest[0].to_lowercase()),
68                "LPUSH" if rest.len() == 2 => Command::LPush(rest[0].to_lowercase(), rest[1].to_string()),
69                "RPUSH" if rest.len() == 2 => Command::RPush(rest[0].to_lowercase(), rest[1].to_string()),
70                "LPOP" if rest.len() == 1 => Command::LPop(rest[0].to_lowercase()),
71                "RPOP" if rest.len() == 1 => Command::RPop(rest[0].to_lowercase()),
72                "LLEN" if rest.len() == 1 => Command::LLen(rest[0].to_lowercase()),
73                "MULTI" if rest.is_empty() => Command::Multi,
74                "EXEC" if rest.is_empty() => Command::Exec,
75                "DISCARD" if rest.is_empty() => Command::Discard,
76                _ => Command::Unknown(input.to_string()),
77            },
78            _ => Command::Unknown("".to_string()),
79        }
80    }
81}