in_memory_cache/
utils.rs

1//! Utility functions for buffer parsing and manipulation.
2
3use bytes::{Buf, BytesMut};
4
5use crate::error::{CacheError, CacheResult};
6
7/// Receives buffer and converts it to vector of strings.
8///
9/// Splits the buffer on space characters. Note that this simple
10/// implementation doesn't handle quoted strings or escaping.
11///
12/// # Arguments
13/// * `buf` - The buffer to parse. Will be consumed.
14///
15/// # Returns
16/// A vector of strings, split by spaces.
17///
18/// # Example
19/// ```ignore
20/// let mut buf = BytesMut::from("set key value");
21/// let parts = buffer_to_array(&mut buf);
22/// assert_eq!(parts, vec!["set", "key", "value"]);
23/// ```
24pub fn buffer_to_array(buf: &mut BytesMut) -> Vec<String> {
25    let mut vec = vec![];
26    let length = buf.len();
27
28    if length == 0 {
29        return vec;
30    }
31
32    let mut word = String::new();
33
34    for i in 0..length {
35        match buf.get_u8() {
36            // Space indicates end of word
37            b' ' => {
38                if !word.is_empty() {
39                    vec.push(word);
40                    word = String::new();
41                }
42            }
43            // Collect character into current word
44            other => {
45                word.push(other as char);
46                if i == length - 1 && !word.is_empty() {
47                    vec.push(word.clone());
48                }
49            }
50        }
51    }
52    vec
53}
54
55/// Parse a buffer into command parts with validation.
56///
57/// Returns an error if the buffer is empty or malformed.
58///
59/// # Arguments
60/// * `buf` - The buffer to parse. Will be consumed.
61///
62/// # Returns
63/// A vector of at least one string, or an error.
64pub fn parse_command(buf: &mut BytesMut) -> CacheResult<Vec<String>> {
65    let parts = buffer_to_array(buf);
66
67    if parts.is_empty() {
68        return Err(CacheError::ParseError("empty command".to_string()));
69    }
70
71    Ok(parts)
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_buffer_to_array_basic() {
80        let mut buf = BytesMut::from("set key value");
81        let result = buffer_to_array(&mut buf);
82        assert_eq!(result, vec!["set", "key", "value"]);
83    }
84
85    #[test]
86    fn test_buffer_to_array_empty() {
87        let mut buf = BytesMut::new();
88        let result = buffer_to_array(&mut buf);
89        assert!(result.is_empty());
90    }
91
92    #[test]
93    fn test_buffer_to_array_single_word() {
94        let mut buf = BytesMut::from("ping");
95        let result = buffer_to_array(&mut buf);
96        assert_eq!(result, vec!["ping"]);
97    }
98
99    #[test]
100    fn test_buffer_to_array_multiple_spaces() {
101        let mut buf = BytesMut::from("set  key   value");
102        let result = buffer_to_array(&mut buf);
103        // Multiple spaces are treated as single separator
104        assert_eq!(result, vec!["set", "key", "value"]);
105    }
106
107    #[test]
108    fn test_parse_command_empty() {
109        let mut buf = BytesMut::new();
110        let result = parse_command(&mut buf);
111        assert!(result.is_err());
112    }
113
114    #[test]
115    fn test_parse_command_valid() {
116        let mut buf = BytesMut::from("get mykey");
117        let result = parse_command(&mut buf);
118        assert!(result.is_ok());
119        assert_eq!(result.unwrap(), vec!["get", "mykey"]);
120    }
121}