Skip to main content

memcache_proto/
response.rs

1//! Memcache response types and parsing/encoding.
2//!
3//! Response types:
4//! - `VALUE <key> <flags> <bytes>\r\n<data>\r\n... END\r\n` - GET response
5//! - `STORED\r\n` - SET success
6//! - `NOT_STORED\r\n` - SET failure
7//! - `DELETED\r\n` - DELETE success
8//! - `NOT_FOUND\r\n` - DELETE miss
9//! - `ERROR\r\n` - Generic error
10//! - `CLIENT_ERROR <msg>\r\n` - Client error
11//! - `SERVER_ERROR <msg>\r\n` - Server error
12
13use crate::error::ParseError;
14use std::io::Write;
15
16/// A single value from a GET response.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Value {
19    pub key: Vec<u8>,
20    pub flags: u32,
21    pub data: Vec<u8>,
22    /// CAS unique token, present when the response is from a `gets` command.
23    pub cas: Option<u64>,
24}
25
26/// A parsed Memcache response.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum Response {
29    /// Value response from GET (may contain multiple values for multi-get)
30    Values(Vec<Value>),
31    /// STORED response from SET
32    Stored,
33    /// NOT_STORED response from SET
34    NotStored,
35    /// DELETED response from DELETE
36    Deleted,
37    /// NOT_FOUND response from DELETE
38    NotFound,
39    /// EXISTS response from CAS
40    Exists,
41    /// OK response (from flush_all, touch, etc.)
42    Ok,
43    /// Numeric response from INCR/DECR (the new value after the operation).
44    Numeric(u64),
45    /// VERSION response
46    Version(Vec<u8>),
47    /// Generic error
48    Error,
49    /// Client error with message
50    ClientError(Vec<u8>),
51    /// Server error with message
52    ServerError(Vec<u8>),
53}
54
55impl Response {
56    // ========================================================================
57    // Constructors (for server-side encoding)
58    // ========================================================================
59
60    /// Create a STORED response.
61    #[inline]
62    pub fn stored() -> Self {
63        Response::Stored
64    }
65
66    /// Create a NOT_STORED response.
67    #[inline]
68    pub fn not_stored() -> Self {
69        Response::NotStored
70    }
71
72    /// Create a DELETED response.
73    #[inline]
74    pub fn deleted() -> Self {
75        Response::Deleted
76    }
77
78    /// Create a NOT_FOUND response.
79    #[inline]
80    pub fn not_found() -> Self {
81        Response::NotFound
82    }
83
84    /// Create an OK response.
85    #[inline]
86    pub fn ok() -> Self {
87        Response::Ok
88    }
89
90    /// Create a numeric response (from INCR/DECR).
91    #[inline]
92    pub fn numeric(value: u64) -> Self {
93        Response::Numeric(value)
94    }
95
96    /// Create an empty VALUES response (cache miss).
97    #[inline]
98    pub fn miss() -> Self {
99        Response::Values(vec![])
100    }
101
102    /// Create a VALUES response with a single value (cache hit).
103    #[inline]
104    pub fn hit(key: &[u8], flags: u32, data: &[u8]) -> Self {
105        Response::Values(vec![Value {
106            key: key.to_vec(),
107            flags,
108            data: data.to_vec(),
109            cas: None,
110        }])
111    }
112
113    /// Create an ERROR response.
114    #[inline]
115    pub fn error() -> Self {
116        Response::Error
117    }
118
119    /// Create a CLIENT_ERROR response.
120    #[inline]
121    pub fn client_error(msg: &[u8]) -> Self {
122        Response::ClientError(msg.to_vec())
123    }
124
125    /// Create a SERVER_ERROR response.
126    #[inline]
127    pub fn server_error(msg: &[u8]) -> Self {
128        Response::ServerError(msg.to_vec())
129    }
130
131    // ========================================================================
132    // Type checks
133    // ========================================================================
134
135    /// Returns true if this is an error response.
136    #[inline]
137    pub fn is_error(&self) -> bool {
138        matches!(
139            self,
140            Response::Error | Response::ClientError(_) | Response::ServerError(_)
141        )
142    }
143
144    /// Returns true if this represents a cache miss.
145    #[inline]
146    pub fn is_miss(&self) -> bool {
147        match self {
148            Response::Values(values) => values.is_empty(),
149            Response::NotFound => true,
150            _ => false,
151        }
152    }
153
154    /// Returns true if this is a successful storage response.
155    #[inline]
156    pub fn is_stored(&self) -> bool {
157        matches!(self, Response::Stored)
158    }
159
160    // ========================================================================
161    // Parsing (client-side)
162    // ========================================================================
163
164    /// Parse a response from a byte buffer.
165    ///
166    /// Returns the parsed response and the number of bytes consumed.
167    #[inline]
168    pub fn parse(data: &[u8]) -> Result<(Self, usize), ParseError> {
169        // Find the first line
170        let line_end = find_crlf(data).ok_or(ParseError::Incomplete)?;
171        let line = &data[..line_end];
172
173        // Check for simple responses first
174        if line == b"STORED" {
175            return Ok((Response::Stored, line_end + 2));
176        }
177        if line == b"NOT_STORED" {
178            return Ok((Response::NotStored, line_end + 2));
179        }
180        if line == b"DELETED" {
181            return Ok((Response::Deleted, line_end + 2));
182        }
183        if line == b"NOT_FOUND" {
184            return Ok((Response::NotFound, line_end + 2));
185        }
186        if line == b"EXISTS" {
187            return Ok((Response::Exists, line_end + 2));
188        }
189        if line == b"END" {
190            // Empty GET response (miss)
191            return Ok((Response::Values(vec![]), line_end + 2));
192        }
193        if line == b"OK" {
194            return Ok((Response::Ok, line_end + 2));
195        }
196        if line == b"ERROR" {
197            return Ok((Response::Error, line_end + 2));
198        }
199        if line.starts_with(b"CLIENT_ERROR ") {
200            let msg = line[13..].to_vec();
201            return Ok((Response::ClientError(msg), line_end + 2));
202        }
203        if line.starts_with(b"SERVER_ERROR ") {
204            let msg = line[13..].to_vec();
205            return Ok((Response::ServerError(msg), line_end + 2));
206        }
207        if line.starts_with(b"VERSION ") {
208            let version = line[8..].to_vec();
209            return Ok((Response::Version(version), line_end + 2));
210        }
211
212        // Check for VALUE response
213        if line.starts_with(b"VALUE ") {
214            return parse_value_response(data);
215        }
216
217        // Check for numeric response (INCR/DECR returns `<number>\r\n`)
218        if !line.is_empty() && line.iter().all(|&b| b.is_ascii_digit()) {
219            let value = parse_u64(line)?;
220            return Ok((Response::Numeric(value), line_end + 2));
221        }
222
223        Err(ParseError::Protocol("unknown response"))
224    }
225
226    // ========================================================================
227    // Encoding (server-side)
228    // ========================================================================
229
230    /// Encode this response into a buffer.
231    ///
232    /// Returns the number of bytes written.
233    pub fn encode(&self, buf: &mut [u8]) -> usize {
234        match self {
235            Response::Stored => {
236                buf[..8].copy_from_slice(b"STORED\r\n");
237                8
238            }
239            Response::NotStored => {
240                buf[..12].copy_from_slice(b"NOT_STORED\r\n");
241                12
242            }
243            Response::Deleted => {
244                buf[..9].copy_from_slice(b"DELETED\r\n");
245                9
246            }
247            Response::NotFound => {
248                buf[..11].copy_from_slice(b"NOT_FOUND\r\n");
249                11
250            }
251            Response::Exists => {
252                buf[..8].copy_from_slice(b"EXISTS\r\n");
253                8
254            }
255            Response::Ok => {
256                buf[..4].copy_from_slice(b"OK\r\n");
257                4
258            }
259            Response::Numeric(value) => {
260                let mut cursor = std::io::Cursor::new(&mut buf[..]);
261                write!(cursor, "{}\r\n", value).unwrap();
262                cursor.position() as usize
263            }
264            Response::Error => {
265                buf[..7].copy_from_slice(b"ERROR\r\n");
266                7
267            }
268            Response::ClientError(msg) => {
269                let mut pos = 0;
270                buf[pos..pos + 13].copy_from_slice(b"CLIENT_ERROR ");
271                pos += 13;
272                buf[pos..pos + msg.len()].copy_from_slice(msg);
273                pos += msg.len();
274                buf[pos..pos + 2].copy_from_slice(b"\r\n");
275                pos + 2
276            }
277            Response::ServerError(msg) => {
278                let mut pos = 0;
279                buf[pos..pos + 13].copy_from_slice(b"SERVER_ERROR ");
280                pos += 13;
281                buf[pos..pos + msg.len()].copy_from_slice(msg);
282                pos += msg.len();
283                buf[pos..pos + 2].copy_from_slice(b"\r\n");
284                pos + 2
285            }
286            Response::Version(v) => {
287                let mut pos = 0;
288                buf[pos..pos + 8].copy_from_slice(b"VERSION ");
289                pos += 8;
290                buf[pos..pos + v.len()].copy_from_slice(v);
291                pos += v.len();
292                buf[pos..pos + 2].copy_from_slice(b"\r\n");
293                pos + 2
294            }
295            Response::Values(values) => encode_values(buf, values),
296        }
297    }
298
299    // ========================================================================
300    // Direct encoding helpers (for server hot path)
301    // ========================================================================
302
303    /// Encode STORED directly to buffer.
304    #[inline]
305    pub fn encode_stored(buf: &mut [u8]) -> usize {
306        buf[..8].copy_from_slice(b"STORED\r\n");
307        8
308    }
309
310    /// Encode NOT_STORED directly to buffer.
311    #[inline]
312    pub fn encode_not_stored(buf: &mut [u8]) -> usize {
313        buf[..12].copy_from_slice(b"NOT_STORED\r\n");
314        12
315    }
316
317    /// Encode DELETED directly to buffer.
318    #[inline]
319    pub fn encode_deleted(buf: &mut [u8]) -> usize {
320        buf[..9].copy_from_slice(b"DELETED\r\n");
321        9
322    }
323
324    /// Encode NOT_FOUND directly to buffer.
325    #[inline]
326    pub fn encode_not_found(buf: &mut [u8]) -> usize {
327        buf[..11].copy_from_slice(b"NOT_FOUND\r\n");
328        11
329    }
330
331    /// Encode END (empty get response) directly to buffer.
332    #[inline]
333    pub fn encode_end(buf: &mut [u8]) -> usize {
334        buf[..5].copy_from_slice(b"END\r\n");
335        5
336    }
337
338    /// Encode a single VALUE response directly to buffer.
339    #[inline]
340    pub fn encode_value(buf: &mut [u8], key: &[u8], flags: u32, data: &[u8]) -> usize {
341        let mut pos = 0;
342
343        // VALUE <key> <flags> <bytes>\r\n
344        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
345        pos += 6;
346        buf[pos..pos + key.len()].copy_from_slice(key);
347        pos += key.len();
348        buf[pos] = b' ';
349        pos += 1;
350
351        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
352        write!(cursor, "{} {}\r\n", flags, data.len()).unwrap();
353        pos += cursor.position() as usize;
354
355        // <data>\r\n
356        buf[pos..pos + data.len()].copy_from_slice(data);
357        pos += data.len();
358        buf[pos..pos + 2].copy_from_slice(b"\r\n");
359        pos += 2;
360
361        // END\r\n
362        buf[pos..pos + 5].copy_from_slice(b"END\r\n");
363        pos + 5
364    }
365
366    /// Encode a single VALUE response with CAS token directly to buffer (GETS response).
367    ///
368    /// Format: `VALUE <key> <flags> <bytes> <cas>\r\n<data>\r\nEND\r\n`
369    #[inline]
370    pub fn encode_value_with_cas(
371        buf: &mut [u8],
372        key: &[u8],
373        flags: u32,
374        data: &[u8],
375        cas: u64,
376    ) -> usize {
377        let mut pos = 0;
378
379        // VALUE <key> <flags> <bytes> <cas>\r\n
380        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
381        pos += 6;
382        buf[pos..pos + key.len()].copy_from_slice(key);
383        pos += key.len();
384        buf[pos] = b' ';
385        pos += 1;
386
387        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
388        write!(cursor, "{} {} {}\r\n", flags, data.len(), cas).unwrap();
389        pos += cursor.position() as usize;
390
391        // <data>\r\n
392        buf[pos..pos + data.len()].copy_from_slice(data);
393        pos += data.len();
394        buf[pos..pos + 2].copy_from_slice(b"\r\n");
395        pos += 2;
396
397        // END\r\n
398        buf[pos..pos + 5].copy_from_slice(b"END\r\n");
399        pos + 5
400    }
401
402    /// Encode EXISTS response directly to buffer.
403    #[inline]
404    pub fn encode_exists(buf: &mut [u8]) -> usize {
405        buf[..8].copy_from_slice(b"EXISTS\r\n");
406        8
407    }
408
409    /// Encode a numeric response directly to buffer (INCR/DECR result).
410    #[inline]
411    pub fn encode_numeric(buf: &mut [u8], value: u64) -> usize {
412        let mut cursor = std::io::Cursor::new(&mut buf[..]);
413        write!(cursor, "{}\r\n", value).unwrap();
414        cursor.position() as usize
415    }
416
417    /// Encode a SERVER_ERROR response directly to buffer.
418    #[inline]
419    pub fn encode_server_error(buf: &mut [u8], msg: &[u8]) -> usize {
420        let mut pos = 0;
421        buf[pos..pos + 13].copy_from_slice(b"SERVER_ERROR ");
422        pos += 13;
423        buf[pos..pos + msg.len()].copy_from_slice(msg);
424        pos += msg.len();
425        buf[pos..pos + 2].copy_from_slice(b"\r\n");
426        pos + 2
427    }
428}
429
430/// Find \r\n in data, return position of \r
431fn find_crlf(data: &[u8]) -> Option<usize> {
432    memchr::memchr(b'\r', data).and_then(|pos| {
433        if pos + 1 < data.len() && data[pos + 1] == b'\n' {
434            Some(pos)
435        } else {
436            None
437        }
438    })
439}
440
441/// Parse a VALUE response (potentially with multiple values).
442fn parse_value_response(data: &[u8]) -> Result<(Response, usize), ParseError> {
443    let mut values = Vec::new();
444    let mut pos = 0;
445
446    loop {
447        // Find the line end
448        let remaining = &data[pos..];
449        let line_end = find_crlf(remaining).ok_or(ParseError::Incomplete)?;
450        let line = &remaining[..line_end];
451
452        // Check for END
453        if line == b"END" {
454            pos += line_end + 2;
455            break;
456        }
457
458        // Parse VALUE line: VALUE <key> <flags> <bytes> [<cas unique>]
459        if !line.starts_with(b"VALUE ") {
460            return Err(ParseError::Protocol("expected VALUE or END"));
461        }
462
463        let parts: Vec<&[u8]> = line[6..].split(|&b| b == b' ').collect();
464        if parts.len() < 3 {
465            return Err(ParseError::Protocol("invalid VALUE line"));
466        }
467
468        let key = parts[0].to_vec();
469        let flags = parse_u32(parts[1])?;
470        let bytes = parse_usize(parts[2])?;
471        let cas = if parts.len() >= 4 {
472            Some(parse_u64(parts[3])?)
473        } else {
474            None
475        };
476
477        // Move past the VALUE line
478        pos += line_end + 2;
479
480        // Read the data
481        let data_end = pos + bytes;
482        if data.len() < data_end + 2 {
483            return Err(ParseError::Incomplete);
484        }
485
486        // Verify trailing \r\n
487        if data[data_end] != b'\r' || data[data_end + 1] != b'\n' {
488            return Err(ParseError::Protocol("missing data terminator"));
489        }
490
491        let value_data = data[pos..data_end].to_vec();
492        pos = data_end + 2;
493
494        values.push(Value {
495            key,
496            flags,
497            data: value_data,
498            cas,
499        });
500    }
501
502    Ok((Response::Values(values), pos))
503}
504
505/// Encode multiple values as a response.
506fn encode_values(buf: &mut [u8], values: &[Value]) -> usize {
507    let mut pos = 0;
508
509    for value in values {
510        // VALUE <key> <flags> <bytes> [<cas>]\r\n
511        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
512        pos += 6;
513        buf[pos..pos + value.key.len()].copy_from_slice(&value.key);
514        pos += value.key.len();
515        buf[pos] = b' ';
516        pos += 1;
517
518        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
519        if let Some(cas) = value.cas {
520            write!(cursor, "{} {} {}\r\n", value.flags, value.data.len(), cas).unwrap();
521        } else {
522            write!(cursor, "{} {}\r\n", value.flags, value.data.len()).unwrap();
523        }
524        pos += cursor.position() as usize;
525
526        // <data>\r\n
527        buf[pos..pos + value.data.len()].copy_from_slice(&value.data);
528        pos += value.data.len();
529        buf[pos..pos + 2].copy_from_slice(b"\r\n");
530        pos += 2;
531    }
532
533    // END\r\n
534    buf[pos..pos + 5].copy_from_slice(b"END\r\n");
535    pos + 5
536}
537
538/// Parse a u32 from ASCII decimal.
539fn parse_u32(data: &[u8]) -> Result<u32, ParseError> {
540    std::str::from_utf8(data)
541        .map_err(|_| ParseError::InvalidNumber)?
542        .parse()
543        .map_err(|_| ParseError::InvalidNumber)
544}
545
546/// Parse a u64 from ASCII decimal.
547fn parse_u64(data: &[u8]) -> Result<u64, ParseError> {
548    std::str::from_utf8(data)
549        .map_err(|_| ParseError::InvalidNumber)?
550        .parse()
551        .map_err(|_| ParseError::InvalidNumber)
552}
553
554/// Maximum value data size (1MB, matching DEFAULT_MAX_VALUE_LEN).
555const MAX_VALUE_DATA_LEN: usize = 1024 * 1024;
556
557/// Parse a usize from ASCII decimal, with a maximum limit.
558fn parse_usize(data: &[u8]) -> Result<usize, ParseError> {
559    let value: usize = std::str::from_utf8(data)
560        .map_err(|_| ParseError::InvalidNumber)?
561        .parse()
562        .map_err(|_| ParseError::InvalidNumber)?;
563
564    if value > MAX_VALUE_DATA_LEN {
565        return Err(ParseError::Protocol("value data too large"));
566    }
567
568    Ok(value)
569}
570
571#[cfg(test)]
572mod tests {
573    use super::*;
574
575    #[test]
576    fn test_parse_stored() {
577        let (resp, consumed) = Response::parse(b"STORED\r\n").unwrap();
578        assert_eq!(resp, Response::Stored);
579        assert_eq!(consumed, 8);
580    }
581
582    #[test]
583    fn test_parse_not_stored() {
584        let (resp, consumed) = Response::parse(b"NOT_STORED\r\n").unwrap();
585        assert_eq!(resp, Response::NotStored);
586        assert_eq!(consumed, 12);
587    }
588
589    #[test]
590    fn test_parse_deleted() {
591        let (resp, consumed) = Response::parse(b"DELETED\r\n").unwrap();
592        assert_eq!(resp, Response::Deleted);
593        assert_eq!(consumed, 9);
594    }
595
596    #[test]
597    fn test_parse_not_found() {
598        let (resp, consumed) = Response::parse(b"NOT_FOUND\r\n").unwrap();
599        assert_eq!(resp, Response::NotFound);
600        assert_eq!(consumed, 11);
601    }
602
603    #[test]
604    fn test_parse_end() {
605        let (resp, consumed) = Response::parse(b"END\r\n").unwrap();
606        assert_eq!(resp, Response::Values(vec![]));
607        assert_eq!(consumed, 5);
608        assert!(resp.is_miss());
609    }
610
611    #[test]
612    fn test_parse_value() {
613        let data = b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n";
614        let (resp, consumed) = Response::parse(data).unwrap();
615        assert_eq!(consumed, data.len());
616        match resp {
617            Response::Values(values) => {
618                assert_eq!(values.len(), 1);
619                assert_eq!(values[0].key, b"mykey");
620                assert_eq!(values[0].flags, 0);
621                assert_eq!(values[0].data, b"myvalue");
622            }
623            _ => panic!("expected Values"),
624        }
625    }
626
627    #[test]
628    fn test_parse_multi_value() {
629        let data = b"VALUE key1 0 3\r\nfoo\r\nVALUE key2 0 3\r\nbar\r\nEND\r\n";
630        let (resp, consumed) = Response::parse(data).unwrap();
631        assert_eq!(consumed, data.len());
632        match resp {
633            Response::Values(values) => {
634                assert_eq!(values.len(), 2);
635                assert_eq!(values[0].key, b"key1");
636                assert_eq!(values[0].data, b"foo");
637                assert_eq!(values[1].key, b"key2");
638                assert_eq!(values[1].data, b"bar");
639            }
640            _ => panic!("expected Values"),
641        }
642    }
643
644    #[test]
645    fn test_parse_error() {
646        let (resp, _) = Response::parse(b"ERROR\r\n").unwrap();
647        assert!(resp.is_error());
648    }
649
650    #[test]
651    fn test_parse_server_error() {
652        let (resp, _) = Response::parse(b"SERVER_ERROR out of memory\r\n").unwrap();
653        assert!(resp.is_error());
654        match resp {
655            Response::ServerError(msg) => assert_eq!(msg, b"out of memory"),
656            _ => panic!("expected ServerError"),
657        }
658    }
659
660    #[test]
661    fn test_parse_incomplete() {
662        assert!(matches!(
663            Response::parse(b"VALUE mykey 0 7\r\nmyval"),
664            Err(ParseError::Incomplete)
665        ));
666    }
667
668    #[test]
669    fn test_encode_stored() {
670        let mut buf = [0u8; 64];
671        let len = Response::stored().encode(&mut buf);
672        assert_eq!(&buf[..len], b"STORED\r\n");
673    }
674
675    #[test]
676    fn test_encode_deleted() {
677        let mut buf = [0u8; 64];
678        let len = Response::deleted().encode(&mut buf);
679        assert_eq!(&buf[..len], b"DELETED\r\n");
680    }
681
682    #[test]
683    fn test_encode_value() {
684        let mut buf = [0u8; 128];
685        let len = Response::encode_value(&mut buf, b"mykey", 0, b"myvalue");
686        assert_eq!(&buf[..len], b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n");
687    }
688
689    #[test]
690    fn test_encode_miss() {
691        let mut buf = [0u8; 64];
692        let len = Response::miss().encode(&mut buf);
693        assert_eq!(&buf[..len], b"END\r\n");
694    }
695
696    #[test]
697    fn test_roundtrip() {
698        let mut buf = [0u8; 256];
699
700        // Test simple responses
701        let responses = vec![
702            Response::stored(),
703            Response::not_stored(),
704            Response::deleted(),
705            Response::not_found(),
706            Response::ok(),
707            Response::numeric(0),
708            Response::numeric(42),
709            Response::numeric(18446744073709551615),
710            Response::error(),
711            Response::miss(),
712        ];
713
714        for original in responses {
715            let len = original.encode(&mut buf);
716            let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
717            assert_eq!(original, parsed);
718            assert_eq!(len, consumed);
719        }
720    }
721
722    // Additional tests for improved coverage
723
724    #[test]
725    fn test_parse_exists() {
726        let (resp, consumed) = Response::parse(b"EXISTS\r\n").unwrap();
727        assert_eq!(resp, Response::Exists);
728        assert_eq!(consumed, 8);
729    }
730
731    #[test]
732    fn test_parse_client_error() {
733        let (resp, consumed) = Response::parse(b"CLIENT_ERROR bad request\r\n").unwrap();
734        assert!(resp.is_error());
735        assert_eq!(consumed, 26);
736        match resp {
737            Response::ClientError(msg) => assert_eq!(msg, b"bad request"),
738            _ => panic!("expected ClientError"),
739        }
740    }
741
742    #[test]
743    fn test_parse_version() {
744        let (resp, consumed) = Response::parse(b"VERSION 1.6.9\r\n").unwrap();
745        assert_eq!(consumed, 15);
746        match resp {
747            Response::Version(v) => assert_eq!(v, b"1.6.9"),
748            _ => panic!("expected Version"),
749        }
750    }
751
752    #[test]
753    fn test_parse_unknown_response() {
754        let result = Response::parse(b"UNKNOWN\r\n");
755        assert!(matches!(
756            result,
757            Err(ParseError::Protocol("unknown response"))
758        ));
759    }
760
761    #[test]
762    fn test_parse_incomplete_no_crlf() {
763        assert!(matches!(
764            Response::parse(b"STORED"),
765            Err(ParseError::Incomplete)
766        ));
767    }
768
769    #[test]
770    fn test_parse_value_incomplete_data() {
771        // VALUE line complete but data incomplete
772        assert!(matches!(
773            Response::parse(b"VALUE k 0 10\r\nshort\r\nEND\r\n"),
774            Err(ParseError::Incomplete)
775        ));
776    }
777
778    #[test]
779    fn test_parse_value_missing_terminator() {
780        // Data is correct length but missing \r\n terminator
781        assert!(matches!(
782            Response::parse(b"VALUE k 0 5\r\nhelloXXEND\r\n"),
783            Err(ParseError::Protocol("missing data terminator"))
784        ));
785    }
786
787    #[test]
788    fn test_parse_value_invalid_format() {
789        // VALUE line with too few parts
790        assert!(matches!(
791            Response::parse(b"VALUE k\r\nEND\r\n"),
792            Err(ParseError::Protocol("invalid VALUE line"))
793        ));
794    }
795
796    #[test]
797    fn test_parse_value_invalid_flags() {
798        // Non-numeric flags
799        assert!(matches!(
800            Response::parse(b"VALUE k abc 5\r\nhello\r\nEND\r\n"),
801            Err(ParseError::InvalidNumber)
802        ));
803    }
804
805    #[test]
806    fn test_parse_value_invalid_bytes() {
807        // Non-numeric bytes
808        assert!(matches!(
809            Response::parse(b"VALUE k 0 xyz\r\nhello\r\nEND\r\n"),
810            Err(ParseError::InvalidNumber)
811        ));
812    }
813
814    #[test]
815    fn test_parse_value_expected_end() {
816        // After VALUE data, expect END or another VALUE
817        assert!(matches!(
818            Response::parse(b"VALUE k 0 5\r\nhello\r\nSTORED\r\n"),
819            Err(ParseError::Protocol("expected VALUE or END"))
820        ));
821    }
822
823    #[test]
824    fn test_parse_ok() {
825        let (resp, consumed) = Response::parse(b"OK\r\n").unwrap();
826        assert_eq!(resp, Response::Ok);
827        assert_eq!(consumed, 4);
828    }
829
830    #[test]
831    fn test_encode_ok() {
832        let mut buf = [0u8; 64];
833        let len = Response::ok().encode(&mut buf);
834        assert_eq!(&buf[..len], b"OK\r\n");
835    }
836
837    #[test]
838    fn test_parse_numeric() {
839        let (resp, consumed) = Response::parse(b"42\r\n").unwrap();
840        assert_eq!(resp, Response::Numeric(42));
841        assert_eq!(consumed, 4);
842    }
843
844    #[test]
845    fn test_parse_numeric_zero() {
846        let (resp, consumed) = Response::parse(b"0\r\n").unwrap();
847        assert_eq!(resp, Response::Numeric(0));
848        assert_eq!(consumed, 3);
849    }
850
851    #[test]
852    fn test_parse_numeric_large() {
853        let (resp, consumed) = Response::parse(b"18446744073709551615\r\n").unwrap();
854        assert_eq!(resp, Response::Numeric(u64::MAX));
855        assert_eq!(consumed, 22);
856    }
857
858    #[test]
859    fn test_encode_numeric() {
860        let mut buf = [0u8; 64];
861        let len = Response::numeric(42).encode(&mut buf);
862        assert_eq!(&buf[..len], b"42\r\n");
863    }
864
865    #[test]
866    fn test_encode_numeric_zero() {
867        let mut buf = [0u8; 64];
868        let len = Response::numeric(0).encode(&mut buf);
869        assert_eq!(&buf[..len], b"0\r\n");
870    }
871
872    #[test]
873    fn test_direct_encode_numeric() {
874        let mut buf = [0u8; 64];
875        let len = Response::encode_numeric(&mut buf, 12345);
876        assert_eq!(&buf[..len], b"12345\r\n");
877    }
878
879    #[test]
880    fn test_is_error_variants() {
881        assert!(Response::Error.is_error());
882        assert!(Response::ClientError(b"msg".to_vec()).is_error());
883        assert!(Response::ServerError(b"msg".to_vec()).is_error());
884        assert!(!Response::Stored.is_error());
885        assert!(!Response::NotStored.is_error());
886        assert!(!Response::Deleted.is_error());
887        assert!(!Response::NotFound.is_error());
888        assert!(!Response::Exists.is_error());
889        assert!(!Response::Ok.is_error());
890        assert!(!Response::Numeric(42).is_error());
891        assert!(!Response::Values(vec![]).is_error());
892        assert!(!Response::Version(b"1.0".to_vec()).is_error());
893    }
894
895    #[test]
896    fn test_is_miss_variants() {
897        // Empty values is a miss
898        assert!(Response::Values(vec![]).is_miss());
899        // NotFound is a miss
900        assert!(Response::NotFound.is_miss());
901        // Non-empty values is not a miss
902        assert!(
903            !Response::Values(vec![Value {
904                key: b"k".to_vec(),
905                flags: 0,
906                data: b"v".to_vec(),
907                cas: None,
908            }])
909            .is_miss()
910        );
911        // Other responses are not misses
912        assert!(!Response::Stored.is_miss());
913        assert!(!Response::Deleted.is_miss());
914        assert!(!Response::Ok.is_miss());
915        assert!(!Response::Numeric(0).is_miss());
916        assert!(!Response::Error.is_miss());
917    }
918
919    #[test]
920    fn test_is_stored_variants() {
921        assert!(Response::Stored.is_stored());
922        assert!(!Response::NotStored.is_stored());
923        assert!(!Response::Deleted.is_stored());
924        assert!(!Response::Error.is_stored());
925    }
926
927    #[test]
928    fn test_encode_not_stored() {
929        let mut buf = [0u8; 64];
930        let len = Response::not_stored().encode(&mut buf);
931        assert_eq!(&buf[..len], b"NOT_STORED\r\n");
932    }
933
934    #[test]
935    fn test_encode_not_found() {
936        let mut buf = [0u8; 64];
937        let len = Response::not_found().encode(&mut buf);
938        assert_eq!(&buf[..len], b"NOT_FOUND\r\n");
939    }
940
941    #[test]
942    fn test_encode_exists() {
943        let mut buf = [0u8; 64];
944        let len = Response::Exists.encode(&mut buf);
945        assert_eq!(&buf[..len], b"EXISTS\r\n");
946    }
947
948    #[test]
949    fn test_encode_error() {
950        let mut buf = [0u8; 64];
951        let len = Response::error().encode(&mut buf);
952        assert_eq!(&buf[..len], b"ERROR\r\n");
953    }
954
955    #[test]
956    fn test_encode_client_error() {
957        let mut buf = [0u8; 64];
958        let len = Response::client_error(b"bad request").encode(&mut buf);
959        assert_eq!(&buf[..len], b"CLIENT_ERROR bad request\r\n");
960    }
961
962    #[test]
963    fn test_encode_server_error() {
964        let mut buf = [0u8; 64];
965        let len = Response::server_error(b"out of memory").encode(&mut buf);
966        assert_eq!(&buf[..len], b"SERVER_ERROR out of memory\r\n");
967    }
968
969    #[test]
970    fn test_encode_version() {
971        let mut buf = [0u8; 64];
972        let len = Response::Version(b"1.6.9".to_vec()).encode(&mut buf);
973        assert_eq!(&buf[..len], b"VERSION 1.6.9\r\n");
974    }
975
976    #[test]
977    fn test_encode_hit() {
978        let mut buf = [0u8; 128];
979        let resp = Response::hit(b"mykey", 42, b"myvalue");
980        let len = resp.encode(&mut buf);
981        assert_eq!(&buf[..len], b"VALUE mykey 42 7\r\nmyvalue\r\nEND\r\n");
982    }
983
984    #[test]
985    fn test_encode_multi_values() {
986        let mut buf = [0u8; 256];
987        let resp = Response::Values(vec![
988            Value {
989                key: b"k1".to_vec(),
990                flags: 0,
991                data: b"v1".to_vec(),
992                cas: None,
993            },
994            Value {
995                key: b"k2".to_vec(),
996                flags: 1,
997                data: b"v2".to_vec(),
998                cas: None,
999            },
1000        ]);
1001        let len = resp.encode(&mut buf);
1002        assert_eq!(
1003            &buf[..len],
1004            b"VALUE k1 0 2\r\nv1\r\nVALUE k2 1 2\r\nv2\r\nEND\r\n"
1005        );
1006    }
1007
1008    #[test]
1009    fn test_direct_encode_stored() {
1010        let mut buf = [0u8; 64];
1011        let len = Response::encode_stored(&mut buf);
1012        assert_eq!(&buf[..len], b"STORED\r\n");
1013    }
1014
1015    #[test]
1016    fn test_direct_encode_not_stored() {
1017        let mut buf = [0u8; 64];
1018        let len = Response::encode_not_stored(&mut buf);
1019        assert_eq!(&buf[..len], b"NOT_STORED\r\n");
1020    }
1021
1022    #[test]
1023    fn test_direct_encode_deleted() {
1024        let mut buf = [0u8; 64];
1025        let len = Response::encode_deleted(&mut buf);
1026        assert_eq!(&buf[..len], b"DELETED\r\n");
1027    }
1028
1029    #[test]
1030    fn test_direct_encode_not_found() {
1031        let mut buf = [0u8; 64];
1032        let len = Response::encode_not_found(&mut buf);
1033        assert_eq!(&buf[..len], b"NOT_FOUND\r\n");
1034    }
1035
1036    #[test]
1037    fn test_direct_encode_end() {
1038        let mut buf = [0u8; 64];
1039        let len = Response::encode_end(&mut buf);
1040        assert_eq!(&buf[..len], b"END\r\n");
1041    }
1042
1043    #[test]
1044    fn test_direct_encode_server_error() {
1045        let mut buf = [0u8; 64];
1046        let len = Response::encode_server_error(&mut buf, b"error message");
1047        assert_eq!(&buf[..len], b"SERVER_ERROR error message\r\n");
1048    }
1049
1050    #[test]
1051    fn test_roundtrip_client_error() {
1052        let mut buf = [0u8; 256];
1053        let original = Response::client_error(b"test error");
1054        let len = original.encode(&mut buf);
1055        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1056        assert_eq!(original, parsed);
1057        assert_eq!(len, consumed);
1058    }
1059
1060    #[test]
1061    fn test_roundtrip_server_error() {
1062        let mut buf = [0u8; 256];
1063        let original = Response::server_error(b"test error");
1064        let len = original.encode(&mut buf);
1065        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1066        assert_eq!(original, parsed);
1067        assert_eq!(len, consumed);
1068    }
1069
1070    #[test]
1071    fn test_roundtrip_values() {
1072        let mut buf = [0u8; 256];
1073        let original = Response::hit(b"testkey", 123, b"testvalue");
1074        let len = original.encode(&mut buf);
1075        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1076        assert_eq!(original, parsed);
1077        assert_eq!(len, consumed);
1078    }
1079
1080    #[test]
1081    fn test_value_debug() {
1082        let v = Value {
1083            key: b"k".to_vec(),
1084            flags: 0,
1085            data: b"v".to_vec(),
1086            cas: None,
1087        };
1088        let debug_str = format!("{:?}", v);
1089        assert!(debug_str.contains("Value"));
1090    }
1091
1092    #[test]
1093    fn test_value_clone() {
1094        let v1 = Value {
1095            key: b"k".to_vec(),
1096            flags: 42,
1097            data: b"v".to_vec(),
1098            cas: None,
1099        };
1100        let v2 = v1.clone();
1101        assert_eq!(v1, v2);
1102    }
1103
1104    #[test]
1105    fn test_response_debug() {
1106        let resp = Response::Stored;
1107        let debug_str = format!("{:?}", resp);
1108        assert!(debug_str.contains("Stored"));
1109    }
1110
1111    #[test]
1112    fn test_response_clone() {
1113        let r1 = Response::Stored;
1114        let r2 = r1.clone();
1115        assert_eq!(r1, r2);
1116    }
1117
1118    #[test]
1119    fn test_parse_value_with_flags() {
1120        let data = b"VALUE mykey 12345 5\r\nhello\r\nEND\r\n";
1121        let (resp, _) = Response::parse(data).unwrap();
1122        match resp {
1123            Response::Values(values) => {
1124                assert_eq!(values[0].flags, 12345);
1125            }
1126            _ => panic!("expected Values"),
1127        }
1128    }
1129
1130    #[test]
1131    fn test_find_crlf_edge_cases() {
1132        // \r at end without \n
1133        assert!(Response::parse(b"STORED\r").is_err());
1134    }
1135
1136    #[test]
1137    fn test_parse_value_data_too_large() {
1138        // Value data size exceeding MAX_VALUE_DATA_LEN should be rejected
1139        let data = b"VALUE k 0 18446744073709551615\r\n";
1140        let result = Response::parse(data);
1141        assert!(matches!(
1142            result,
1143            Err(ParseError::Protocol("value data too large"))
1144        ));
1145    }
1146
1147    #[test]
1148    fn test_parse_value_with_cas() {
1149        let data = b"VALUE mykey 0 5 12345\r\nhello\r\nEND\r\n";
1150        let (resp, consumed) = Response::parse(data).unwrap();
1151        assert_eq!(consumed, data.len());
1152        match resp {
1153            Response::Values(values) => {
1154                assert_eq!(values.len(), 1);
1155                assert_eq!(values[0].key, b"mykey");
1156                assert_eq!(values[0].data, b"hello");
1157                assert_eq!(values[0].cas, Some(12345));
1158            }
1159            _ => panic!("expected Values"),
1160        }
1161    }
1162
1163    #[test]
1164    fn test_parse_value_without_cas() {
1165        let data = b"VALUE mykey 0 5\r\nhello\r\nEND\r\n";
1166        let (resp, _) = Response::parse(data).unwrap();
1167        match resp {
1168            Response::Values(values) => {
1169                assert_eq!(values[0].cas, None);
1170            }
1171            _ => panic!("expected Values"),
1172        }
1173    }
1174
1175    #[test]
1176    fn test_roundtrip_value_with_cas() {
1177        let mut buf = [0u8; 256];
1178        let original = Response::Values(vec![Value {
1179            key: b"testkey".to_vec(),
1180            flags: 0,
1181            data: b"testvalue".to_vec(),
1182            cas: Some(98765),
1183        }]);
1184        let len = original.encode(&mut buf);
1185        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1186        assert_eq!(original, parsed);
1187        assert_eq!(len, consumed);
1188    }
1189
1190    #[test]
1191    fn test_parse_multi_value_with_cas() {
1192        let data = b"VALUE k1 0 2 100\r\nv1\r\nVALUE k2 0 2 200\r\nv2\r\nEND\r\n";
1193        let (resp, consumed) = Response::parse(data).unwrap();
1194        assert_eq!(consumed, data.len());
1195        match resp {
1196            Response::Values(values) => {
1197                assert_eq!(values.len(), 2);
1198                assert_eq!(values[0].cas, Some(100));
1199                assert_eq!(values[1].cas, Some(200));
1200            }
1201            _ => panic!("expected Values"),
1202        }
1203    }
1204}