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 bytes::Bytes;
15use std::io::Write;
16
17/// A single value from a GET response.
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct Value {
20    pub key: Vec<u8>,
21    pub flags: u32,
22    pub data: Vec<u8>,
23    /// CAS unique token, present when the response is from a `gets` command.
24    pub cas: Option<u64>,
25}
26
27/// A parsed Memcache response.
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub enum Response {
30    /// Value response from GET (may contain multiple values for multi-get)
31    Values(Vec<Value>),
32    /// STORED response from SET
33    Stored,
34    /// NOT_STORED response from SET
35    NotStored,
36    /// DELETED response from DELETE
37    Deleted,
38    /// NOT_FOUND response from DELETE
39    NotFound,
40    /// EXISTS response from CAS
41    Exists,
42    /// OK response (from flush_all, touch, etc.)
43    Ok,
44    /// Numeric response from INCR/DECR (the new value after the operation).
45    Numeric(u64),
46    /// VERSION response
47    Version(Vec<u8>),
48    /// Generic error
49    Error,
50    /// Client error with message
51    ClientError(Vec<u8>),
52    /// Server error with message
53    ServerError(Vec<u8>),
54}
55
56impl Response {
57    // ========================================================================
58    // Constructors (for server-side encoding)
59    // ========================================================================
60
61    /// Create a STORED response.
62    #[inline]
63    pub fn stored() -> Self {
64        Response::Stored
65    }
66
67    /// Create a NOT_STORED response.
68    #[inline]
69    pub fn not_stored() -> Self {
70        Response::NotStored
71    }
72
73    /// Create a DELETED response.
74    #[inline]
75    pub fn deleted() -> Self {
76        Response::Deleted
77    }
78
79    /// Create a NOT_FOUND response.
80    #[inline]
81    pub fn not_found() -> Self {
82        Response::NotFound
83    }
84
85    /// Create an OK response.
86    #[inline]
87    pub fn ok() -> Self {
88        Response::Ok
89    }
90
91    /// Create a numeric response (from INCR/DECR).
92    #[inline]
93    pub fn numeric(value: u64) -> Self {
94        Response::Numeric(value)
95    }
96
97    /// Create an empty VALUES response (cache miss).
98    #[inline]
99    pub fn miss() -> Self {
100        Response::Values(vec![])
101    }
102
103    /// Create a VALUES response with a single value (cache hit).
104    #[inline]
105    pub fn hit(key: &[u8], flags: u32, data: &[u8]) -> Self {
106        Response::Values(vec![Value {
107            key: key.to_vec(),
108            flags,
109            data: data.to_vec(),
110            cas: None,
111        }])
112    }
113
114    /// Create an ERROR response.
115    #[inline]
116    pub fn error() -> Self {
117        Response::Error
118    }
119
120    /// Create a CLIENT_ERROR response.
121    #[inline]
122    pub fn client_error(msg: &[u8]) -> Self {
123        Response::ClientError(msg.to_vec())
124    }
125
126    /// Create a SERVER_ERROR response.
127    #[inline]
128    pub fn server_error(msg: &[u8]) -> Self {
129        Response::ServerError(msg.to_vec())
130    }
131
132    // ========================================================================
133    // Type checks
134    // ========================================================================
135
136    /// Returns true if this is an error response.
137    #[inline]
138    pub fn is_error(&self) -> bool {
139        matches!(
140            self,
141            Response::Error | Response::ClientError(_) | Response::ServerError(_)
142        )
143    }
144
145    /// Returns true if this represents a cache miss.
146    #[inline]
147    pub fn is_miss(&self) -> bool {
148        match self {
149            Response::Values(values) => values.is_empty(),
150            Response::NotFound => true,
151            _ => false,
152        }
153    }
154
155    /// Returns true if this is a successful storage response.
156    #[inline]
157    pub fn is_stored(&self) -> bool {
158        matches!(self, Response::Stored)
159    }
160
161    // ========================================================================
162    // Parsing (client-side)
163    // ========================================================================
164
165    /// Parse a response from a byte buffer.
166    ///
167    /// Returns the parsed response and the number of bytes consumed.
168    #[inline]
169    pub fn parse(data: &[u8]) -> Result<(Self, usize), ParseError> {
170        // Find the first line
171        let line_end = find_crlf(data).ok_or(ParseError::Incomplete)?;
172        let line = &data[..line_end];
173
174        // Check for simple responses first
175        if line == b"STORED" {
176            return Ok((Response::Stored, line_end + 2));
177        }
178        if line == b"NOT_STORED" {
179            return Ok((Response::NotStored, line_end + 2));
180        }
181        if line == b"DELETED" {
182            return Ok((Response::Deleted, line_end + 2));
183        }
184        if line == b"NOT_FOUND" {
185            return Ok((Response::NotFound, line_end + 2));
186        }
187        if line == b"EXISTS" {
188            return Ok((Response::Exists, line_end + 2));
189        }
190        if line == b"END" {
191            // Empty GET response (miss)
192            return Ok((Response::Values(vec![]), line_end + 2));
193        }
194        if line == b"OK" {
195            return Ok((Response::Ok, line_end + 2));
196        }
197        if line == b"ERROR" {
198            return Ok((Response::Error, line_end + 2));
199        }
200        if line.starts_with(b"CLIENT_ERROR ") {
201            let msg = line[13..].to_vec();
202            return Ok((Response::ClientError(msg), line_end + 2));
203        }
204        if line.starts_with(b"SERVER_ERROR ") {
205            let msg = line[13..].to_vec();
206            return Ok((Response::ServerError(msg), line_end + 2));
207        }
208        if line.starts_with(b"VERSION ") {
209            let version = line[8..].to_vec();
210            return Ok((Response::Version(version), line_end + 2));
211        }
212
213        // Check for VALUE response
214        if line.starts_with(b"VALUE ") {
215            return parse_value_response(data);
216        }
217
218        // Check for numeric response (INCR/DECR returns `<number>\r\n`)
219        if !line.is_empty() && line.iter().all(|&b| b.is_ascii_digit()) {
220            let value = parse_u64(line)?;
221            return Ok((Response::Numeric(value), line_end + 2));
222        }
223
224        Err(ParseError::Protocol("unknown response"))
225    }
226
227    // ========================================================================
228    // Encoding (server-side)
229    // ========================================================================
230
231    /// Encode this response into a buffer.
232    ///
233    /// Returns the number of bytes written.
234    pub fn encode(&self, buf: &mut [u8]) -> usize {
235        match self {
236            Response::Stored => {
237                buf[..8].copy_from_slice(b"STORED\r\n");
238                8
239            }
240            Response::NotStored => {
241                buf[..12].copy_from_slice(b"NOT_STORED\r\n");
242                12
243            }
244            Response::Deleted => {
245                buf[..9].copy_from_slice(b"DELETED\r\n");
246                9
247            }
248            Response::NotFound => {
249                buf[..11].copy_from_slice(b"NOT_FOUND\r\n");
250                11
251            }
252            Response::Exists => {
253                buf[..8].copy_from_slice(b"EXISTS\r\n");
254                8
255            }
256            Response::Ok => {
257                buf[..4].copy_from_slice(b"OK\r\n");
258                4
259            }
260            Response::Numeric(value) => {
261                let mut cursor = std::io::Cursor::new(&mut buf[..]);
262                write!(cursor, "{}\r\n", value).unwrap();
263                cursor.position() as usize
264            }
265            Response::Error => {
266                buf[..7].copy_from_slice(b"ERROR\r\n");
267                7
268            }
269            Response::ClientError(msg) => {
270                let mut pos = 0;
271                buf[pos..pos + 13].copy_from_slice(b"CLIENT_ERROR ");
272                pos += 13;
273                buf[pos..pos + msg.len()].copy_from_slice(msg);
274                pos += msg.len();
275                buf[pos..pos + 2].copy_from_slice(b"\r\n");
276                pos + 2
277            }
278            Response::ServerError(msg) => {
279                let mut pos = 0;
280                buf[pos..pos + 13].copy_from_slice(b"SERVER_ERROR ");
281                pos += 13;
282                buf[pos..pos + msg.len()].copy_from_slice(msg);
283                pos += msg.len();
284                buf[pos..pos + 2].copy_from_slice(b"\r\n");
285                pos + 2
286            }
287            Response::Version(v) => {
288                let mut pos = 0;
289                buf[pos..pos + 8].copy_from_slice(b"VERSION ");
290                pos += 8;
291                buf[pos..pos + v.len()].copy_from_slice(v);
292                pos += v.len();
293                buf[pos..pos + 2].copy_from_slice(b"\r\n");
294                pos + 2
295            }
296            Response::Values(values) => encode_values(buf, values),
297        }
298    }
299
300    // ========================================================================
301    // Direct encoding helpers (for server hot path)
302    // ========================================================================
303
304    /// Encode STORED directly to buffer.
305    #[inline]
306    pub fn encode_stored(buf: &mut [u8]) -> usize {
307        buf[..8].copy_from_slice(b"STORED\r\n");
308        8
309    }
310
311    /// Encode NOT_STORED directly to buffer.
312    #[inline]
313    pub fn encode_not_stored(buf: &mut [u8]) -> usize {
314        buf[..12].copy_from_slice(b"NOT_STORED\r\n");
315        12
316    }
317
318    /// Encode DELETED directly to buffer.
319    #[inline]
320    pub fn encode_deleted(buf: &mut [u8]) -> usize {
321        buf[..9].copy_from_slice(b"DELETED\r\n");
322        9
323    }
324
325    /// Encode NOT_FOUND directly to buffer.
326    #[inline]
327    pub fn encode_not_found(buf: &mut [u8]) -> usize {
328        buf[..11].copy_from_slice(b"NOT_FOUND\r\n");
329        11
330    }
331
332    /// Encode END (empty get response) directly to buffer.
333    #[inline]
334    pub fn encode_end(buf: &mut [u8]) -> usize {
335        buf[..5].copy_from_slice(b"END\r\n");
336        5
337    }
338
339    /// Encode a single VALUE response directly to buffer.
340    #[inline]
341    pub fn encode_value(buf: &mut [u8], key: &[u8], flags: u32, data: &[u8]) -> usize {
342        let mut pos = 0;
343
344        // VALUE <key> <flags> <bytes>\r\n
345        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
346        pos += 6;
347        buf[pos..pos + key.len()].copy_from_slice(key);
348        pos += key.len();
349        buf[pos] = b' ';
350        pos += 1;
351
352        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
353        write!(cursor, "{} {}\r\n", flags, data.len()).unwrap();
354        pos += cursor.position() as usize;
355
356        // <data>\r\n
357        buf[pos..pos + data.len()].copy_from_slice(data);
358        pos += data.len();
359        buf[pos..pos + 2].copy_from_slice(b"\r\n");
360        pos += 2;
361
362        // END\r\n
363        buf[pos..pos + 5].copy_from_slice(b"END\r\n");
364        pos + 5
365    }
366
367    /// Encode a single VALUE response with CAS token directly to buffer (GETS response).
368    ///
369    /// Format: `VALUE <key> <flags> <bytes> <cas>\r\n<data>\r\nEND\r\n`
370    #[inline]
371    pub fn encode_value_with_cas(
372        buf: &mut [u8],
373        key: &[u8],
374        flags: u32,
375        data: &[u8],
376        cas: u64,
377    ) -> usize {
378        let mut pos = 0;
379
380        // VALUE <key> <flags> <bytes> <cas>\r\n
381        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
382        pos += 6;
383        buf[pos..pos + key.len()].copy_from_slice(key);
384        pos += key.len();
385        buf[pos] = b' ';
386        pos += 1;
387
388        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
389        write!(cursor, "{} {} {}\r\n", flags, data.len(), cas).unwrap();
390        pos += cursor.position() as usize;
391
392        // <data>\r\n
393        buf[pos..pos + data.len()].copy_from_slice(data);
394        pos += data.len();
395        buf[pos..pos + 2].copy_from_slice(b"\r\n");
396        pos += 2;
397
398        // END\r\n
399        buf[pos..pos + 5].copy_from_slice(b"END\r\n");
400        pos + 5
401    }
402
403    /// Encode EXISTS response directly to buffer.
404    #[inline]
405    pub fn encode_exists(buf: &mut [u8]) -> usize {
406        buf[..8].copy_from_slice(b"EXISTS\r\n");
407        8
408    }
409
410    /// Encode a numeric response directly to buffer (INCR/DECR result).
411    #[inline]
412    pub fn encode_numeric(buf: &mut [u8], value: u64) -> usize {
413        let mut cursor = std::io::Cursor::new(&mut buf[..]);
414        write!(cursor, "{}\r\n", value).unwrap();
415        cursor.position() as usize
416    }
417
418    /// Encode a SERVER_ERROR response directly to buffer.
419    #[inline]
420    pub fn encode_server_error(buf: &mut [u8], msg: &[u8]) -> usize {
421        let mut pos = 0;
422        buf[pos..pos + 13].copy_from_slice(b"SERVER_ERROR ");
423        pos += 13;
424        buf[pos..pos + msg.len()].copy_from_slice(msg);
425        pos += msg.len();
426        buf[pos..pos + 2].copy_from_slice(b"\r\n");
427        pos + 2
428    }
429}
430
431/// Find \r\n in data, return position of \r
432fn find_crlf(data: &[u8]) -> Option<usize> {
433    memchr::memchr(b'\r', data).and_then(|pos| {
434        if pos + 1 < data.len() && data[pos + 1] == b'\n' {
435            Some(pos)
436        } else {
437            None
438        }
439    })
440}
441
442/// Parse a VALUE response (potentially with multiple values).
443fn parse_value_response(data: &[u8]) -> Result<(Response, usize), ParseError> {
444    let mut values = Vec::new();
445    let mut pos = 0;
446
447    loop {
448        // Find the line end
449        let remaining = &data[pos..];
450        let line_end = find_crlf(remaining).ok_or(ParseError::Incomplete)?;
451        let line = &remaining[..line_end];
452
453        // Check for END
454        if line == b"END" {
455            pos += line_end + 2;
456            break;
457        }
458
459        // Parse VALUE line: VALUE <key> <flags> <bytes> [<cas unique>]
460        if !line.starts_with(b"VALUE ") {
461            return Err(ParseError::Protocol("expected VALUE or END"));
462        }
463
464        let parts: Vec<&[u8]> = line[6..].split(|&b| b == b' ').collect();
465        if parts.len() < 3 {
466            return Err(ParseError::Protocol("invalid VALUE line"));
467        }
468
469        let key = parts[0].to_vec();
470        let flags = parse_u32(parts[1])?;
471        let bytes = parse_usize(parts[2])?;
472        let cas = if parts.len() >= 4 {
473            Some(parse_u64(parts[3])?)
474        } else {
475            None
476        };
477
478        // Move past the VALUE line
479        pos += line_end + 2;
480
481        // Read the data
482        let data_end = pos + bytes;
483        if data.len() < data_end + 2 {
484            return Err(ParseError::Incomplete);
485        }
486
487        // Verify trailing \r\n
488        if data[data_end] != b'\r' || data[data_end + 1] != b'\n' {
489            return Err(ParseError::Protocol("missing data terminator"));
490        }
491
492        let value_data = data[pos..data_end].to_vec();
493        pos = data_end + 2;
494
495        values.push(Value {
496            key,
497            flags,
498            data: value_data,
499            cas,
500        });
501    }
502
503    Ok((Response::Values(values), pos))
504}
505
506// ========================================================================
507// Zero-copy Bytes-based types and parsing
508// ========================================================================
509
510/// A single value from a GET response, using zero-copy `Bytes` references.
511#[derive(Debug, Clone, PartialEq, Eq)]
512pub struct ValueBytes {
513    pub key: Bytes,
514    pub flags: u32,
515    pub data: Bytes,
516    /// CAS unique token, present when the response is from a `gets` command.
517    pub cas: Option<u64>,
518}
519
520/// A parsed Memcache response using zero-copy `Bytes` for string fields.
521#[derive(Debug, Clone, PartialEq, Eq)]
522pub enum ResponseBytes {
523    /// Value response from GET (may contain multiple values for multi-get)
524    Values(Vec<ValueBytes>),
525    /// STORED response from SET
526    Stored,
527    /// NOT_STORED response from SET
528    NotStored,
529    /// DELETED response from DELETE
530    Deleted,
531    /// NOT_FOUND response from DELETE
532    NotFound,
533    /// EXISTS response from CAS
534    Exists,
535    /// OK response (from flush_all, touch, etc.)
536    Ok,
537    /// Numeric response from INCR/DECR (the new value after the operation).
538    Numeric(u64),
539    /// VERSION response
540    Version(Bytes),
541    /// Generic error
542    Error,
543    /// Client error with message
544    ClientError(Bytes),
545    /// Server error with message
546    ServerError(Bytes),
547}
548
549impl ResponseBytes {
550    /// Returns true if this is an error response.
551    #[inline]
552    pub fn is_error(&self) -> bool {
553        matches!(
554            self,
555            ResponseBytes::Error | ResponseBytes::ClientError(_) | ResponseBytes::ServerError(_)
556        )
557    }
558
559    /// Returns true if this represents a cache miss.
560    #[inline]
561    pub fn is_miss(&self) -> bool {
562        match self {
563            ResponseBytes::Values(values) => values.is_empty(),
564            ResponseBytes::NotFound => true,
565            _ => false,
566        }
567    }
568
569    /// Returns true if this is a successful storage response.
570    #[inline]
571    pub fn is_stored(&self) -> bool {
572        matches!(self, ResponseBytes::Stored)
573    }
574
575    /// Parse a response from a `Bytes` buffer, returning zero-copy slices.
576    ///
577    /// Same parsing logic as [`Response::parse`] but returns `Bytes::slice()`
578    /// references into the input buffer instead of copying into `Vec<u8>`.
579    #[inline]
580    pub fn parse(data: Bytes) -> Result<(Self, usize), ParseError> {
581        let line_end = find_crlf(&data).ok_or(ParseError::Incomplete)?;
582        let line = &data[..line_end];
583
584        if line == b"STORED" {
585            return Ok((ResponseBytes::Stored, line_end + 2));
586        }
587        if line == b"NOT_STORED" {
588            return Ok((ResponseBytes::NotStored, line_end + 2));
589        }
590        if line == b"DELETED" {
591            return Ok((ResponseBytes::Deleted, line_end + 2));
592        }
593        if line == b"NOT_FOUND" {
594            return Ok((ResponseBytes::NotFound, line_end + 2));
595        }
596        if line == b"EXISTS" {
597            return Ok((ResponseBytes::Exists, line_end + 2));
598        }
599        if line == b"END" {
600            return Ok((ResponseBytes::Values(vec![]), line_end + 2));
601        }
602        if line == b"OK" {
603            return Ok((ResponseBytes::Ok, line_end + 2));
604        }
605        if line == b"ERROR" {
606            return Ok((ResponseBytes::Error, line_end + 2));
607        }
608        if line.starts_with(b"CLIENT_ERROR ") {
609            let msg = data.slice(13..line_end);
610            return Ok((ResponseBytes::ClientError(msg), line_end + 2));
611        }
612        if line.starts_with(b"SERVER_ERROR ") {
613            let msg = data.slice(13..line_end);
614            return Ok((ResponseBytes::ServerError(msg), line_end + 2));
615        }
616        if line.starts_with(b"VERSION ") {
617            let version = data.slice(8..line_end);
618            return Ok((ResponseBytes::Version(version), line_end + 2));
619        }
620
621        if line.starts_with(b"VALUE ") {
622            return parse_value_response_bytes(&data);
623        }
624
625        if !line.is_empty() && line.iter().all(|&b| b.is_ascii_digit()) {
626            let value = parse_u64(line)?;
627            return Ok((ResponseBytes::Numeric(value), line_end + 2));
628        }
629
630        Err(ParseError::Protocol("unknown response"))
631    }
632}
633
634/// Parse a VALUE response producing zero-copy `ValueBytes` with `Bytes::slice()`.
635fn parse_value_response_bytes(data: &Bytes) -> Result<(ResponseBytes, usize), ParseError> {
636    let mut values = Vec::new();
637    let mut pos = 0;
638
639    loop {
640        let remaining = &data[pos..];
641        let line_end = find_crlf(remaining).ok_or(ParseError::Incomplete)?;
642        let line = &remaining[..line_end];
643
644        if line == b"END" {
645            pos += line_end + 2;
646            break;
647        }
648
649        if !line.starts_with(b"VALUE ") {
650            return Err(ParseError::Protocol("expected VALUE or END"));
651        }
652
653        // Parse: VALUE <key> <flags> <bytes> [<cas>]
654        // We need absolute offsets into `data` for Bytes::slice().
655        let header_start = pos + 6; // skip "VALUE "
656        let header_end = pos + line_end;
657        let header = &data[header_start..header_end];
658
659        let parts: Vec<&[u8]> = header.split(|&b| b == b' ').collect();
660        if parts.len() < 3 {
661            return Err(ParseError::Protocol("invalid VALUE line"));
662        }
663
664        // Compute absolute offset of the key within `data`.
665        let key_start = header_start;
666        let key_end = key_start + parts[0].len();
667        let key = data.slice(key_start..key_end);
668
669        let flags = parse_u32(parts[1])?;
670        let bytes = parse_usize(parts[2])?;
671        let cas = if parts.len() >= 4 {
672            Some(parse_u64(parts[3])?)
673        } else {
674            None
675        };
676
677        // Move past the VALUE line
678        pos += line_end + 2;
679
680        // Read the data
681        let data_end = pos + bytes;
682        if data.len() < data_end + 2 {
683            return Err(ParseError::Incomplete);
684        }
685
686        if data[data_end] != b'\r' || data[data_end + 1] != b'\n' {
687            return Err(ParseError::Protocol("missing data terminator"));
688        }
689
690        let value_data = data.slice(pos..data_end);
691        pos = data_end + 2;
692
693        values.push(ValueBytes {
694            key,
695            flags,
696            data: value_data,
697            cas,
698        });
699    }
700
701    Ok((ResponseBytes::Values(values), pos))
702}
703
704/// Encode multiple values as a response.
705fn encode_values(buf: &mut [u8], values: &[Value]) -> usize {
706    let mut pos = 0;
707
708    for value in values {
709        // VALUE <key> <flags> <bytes> [<cas>]\r\n
710        buf[pos..pos + 6].copy_from_slice(b"VALUE ");
711        pos += 6;
712        buf[pos..pos + value.key.len()].copy_from_slice(&value.key);
713        pos += value.key.len();
714        buf[pos] = b' ';
715        pos += 1;
716
717        let mut cursor = std::io::Cursor::new(&mut buf[pos..]);
718        if let Some(cas) = value.cas {
719            write!(cursor, "{} {} {}\r\n", value.flags, value.data.len(), cas).unwrap();
720        } else {
721            write!(cursor, "{} {}\r\n", value.flags, value.data.len()).unwrap();
722        }
723        pos += cursor.position() as usize;
724
725        // <data>\r\n
726        buf[pos..pos + value.data.len()].copy_from_slice(&value.data);
727        pos += value.data.len();
728        buf[pos..pos + 2].copy_from_slice(b"\r\n");
729        pos += 2;
730    }
731
732    // END\r\n
733    buf[pos..pos + 5].copy_from_slice(b"END\r\n");
734    pos + 5
735}
736
737/// Parse a u32 from ASCII decimal.
738fn parse_u32(data: &[u8]) -> Result<u32, ParseError> {
739    std::str::from_utf8(data)
740        .map_err(|_| ParseError::InvalidNumber)?
741        .parse()
742        .map_err(|_| ParseError::InvalidNumber)
743}
744
745/// Parse a u64 from ASCII decimal.
746fn parse_u64(data: &[u8]) -> Result<u64, ParseError> {
747    std::str::from_utf8(data)
748        .map_err(|_| ParseError::InvalidNumber)?
749        .parse()
750        .map_err(|_| ParseError::InvalidNumber)
751}
752
753/// Maximum value data size (1MB, matching DEFAULT_MAX_VALUE_LEN).
754const MAX_VALUE_DATA_LEN: usize = 1024 * 1024;
755
756/// Parse a usize from ASCII decimal, with a maximum limit.
757fn parse_usize(data: &[u8]) -> Result<usize, ParseError> {
758    let value: usize = std::str::from_utf8(data)
759        .map_err(|_| ParseError::InvalidNumber)?
760        .parse()
761        .map_err(|_| ParseError::InvalidNumber)?;
762
763    if value > MAX_VALUE_DATA_LEN {
764        return Err(ParseError::Protocol("value data too large"));
765    }
766
767    Ok(value)
768}
769
770#[cfg(test)]
771mod tests {
772    use super::*;
773
774    #[test]
775    fn test_parse_stored() {
776        let (resp, consumed) = Response::parse(b"STORED\r\n").unwrap();
777        assert_eq!(resp, Response::Stored);
778        assert_eq!(consumed, 8);
779    }
780
781    #[test]
782    fn test_parse_not_stored() {
783        let (resp, consumed) = Response::parse(b"NOT_STORED\r\n").unwrap();
784        assert_eq!(resp, Response::NotStored);
785        assert_eq!(consumed, 12);
786    }
787
788    #[test]
789    fn test_parse_deleted() {
790        let (resp, consumed) = Response::parse(b"DELETED\r\n").unwrap();
791        assert_eq!(resp, Response::Deleted);
792        assert_eq!(consumed, 9);
793    }
794
795    #[test]
796    fn test_parse_not_found() {
797        let (resp, consumed) = Response::parse(b"NOT_FOUND\r\n").unwrap();
798        assert_eq!(resp, Response::NotFound);
799        assert_eq!(consumed, 11);
800    }
801
802    #[test]
803    fn test_parse_end() {
804        let (resp, consumed) = Response::parse(b"END\r\n").unwrap();
805        assert_eq!(resp, Response::Values(vec![]));
806        assert_eq!(consumed, 5);
807        assert!(resp.is_miss());
808    }
809
810    #[test]
811    fn test_parse_value() {
812        let data = b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n";
813        let (resp, consumed) = Response::parse(data).unwrap();
814        assert_eq!(consumed, data.len());
815        match resp {
816            Response::Values(values) => {
817                assert_eq!(values.len(), 1);
818                assert_eq!(values[0].key, b"mykey");
819                assert_eq!(values[0].flags, 0);
820                assert_eq!(values[0].data, b"myvalue");
821            }
822            _ => panic!("expected Values"),
823        }
824    }
825
826    #[test]
827    fn test_parse_multi_value() {
828        let data = b"VALUE key1 0 3\r\nfoo\r\nVALUE key2 0 3\r\nbar\r\nEND\r\n";
829        let (resp, consumed) = Response::parse(data).unwrap();
830        assert_eq!(consumed, data.len());
831        match resp {
832            Response::Values(values) => {
833                assert_eq!(values.len(), 2);
834                assert_eq!(values[0].key, b"key1");
835                assert_eq!(values[0].data, b"foo");
836                assert_eq!(values[1].key, b"key2");
837                assert_eq!(values[1].data, b"bar");
838            }
839            _ => panic!("expected Values"),
840        }
841    }
842
843    #[test]
844    fn test_parse_error() {
845        let (resp, _) = Response::parse(b"ERROR\r\n").unwrap();
846        assert!(resp.is_error());
847    }
848
849    #[test]
850    fn test_parse_server_error() {
851        let (resp, _) = Response::parse(b"SERVER_ERROR out of memory\r\n").unwrap();
852        assert!(resp.is_error());
853        match resp {
854            Response::ServerError(msg) => assert_eq!(msg, b"out of memory"),
855            _ => panic!("expected ServerError"),
856        }
857    }
858
859    #[test]
860    fn test_parse_incomplete() {
861        assert!(matches!(
862            Response::parse(b"VALUE mykey 0 7\r\nmyval"),
863            Err(ParseError::Incomplete)
864        ));
865    }
866
867    #[test]
868    fn test_encode_stored() {
869        let mut buf = [0u8; 64];
870        let len = Response::stored().encode(&mut buf);
871        assert_eq!(&buf[..len], b"STORED\r\n");
872    }
873
874    #[test]
875    fn test_encode_deleted() {
876        let mut buf = [0u8; 64];
877        let len = Response::deleted().encode(&mut buf);
878        assert_eq!(&buf[..len], b"DELETED\r\n");
879    }
880
881    #[test]
882    fn test_encode_value() {
883        let mut buf = [0u8; 128];
884        let len = Response::encode_value(&mut buf, b"mykey", 0, b"myvalue");
885        assert_eq!(&buf[..len], b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n");
886    }
887
888    #[test]
889    fn test_encode_miss() {
890        let mut buf = [0u8; 64];
891        let len = Response::miss().encode(&mut buf);
892        assert_eq!(&buf[..len], b"END\r\n");
893    }
894
895    #[test]
896    fn test_roundtrip() {
897        let mut buf = [0u8; 256];
898
899        // Test simple responses
900        let responses = vec![
901            Response::stored(),
902            Response::not_stored(),
903            Response::deleted(),
904            Response::not_found(),
905            Response::ok(),
906            Response::numeric(0),
907            Response::numeric(42),
908            Response::numeric(18446744073709551615),
909            Response::error(),
910            Response::miss(),
911        ];
912
913        for original in responses {
914            let len = original.encode(&mut buf);
915            let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
916            assert_eq!(original, parsed);
917            assert_eq!(len, consumed);
918        }
919    }
920
921    // Additional tests for improved coverage
922
923    #[test]
924    fn test_parse_exists() {
925        let (resp, consumed) = Response::parse(b"EXISTS\r\n").unwrap();
926        assert_eq!(resp, Response::Exists);
927        assert_eq!(consumed, 8);
928    }
929
930    #[test]
931    fn test_parse_client_error() {
932        let (resp, consumed) = Response::parse(b"CLIENT_ERROR bad request\r\n").unwrap();
933        assert!(resp.is_error());
934        assert_eq!(consumed, 26);
935        match resp {
936            Response::ClientError(msg) => assert_eq!(msg, b"bad request"),
937            _ => panic!("expected ClientError"),
938        }
939    }
940
941    #[test]
942    fn test_parse_version() {
943        let (resp, consumed) = Response::parse(b"VERSION 1.6.9\r\n").unwrap();
944        assert_eq!(consumed, 15);
945        match resp {
946            Response::Version(v) => assert_eq!(v, b"1.6.9"),
947            _ => panic!("expected Version"),
948        }
949    }
950
951    #[test]
952    fn test_parse_unknown_response() {
953        let result = Response::parse(b"UNKNOWN\r\n");
954        assert!(matches!(
955            result,
956            Err(ParseError::Protocol("unknown response"))
957        ));
958    }
959
960    #[test]
961    fn test_parse_incomplete_no_crlf() {
962        assert!(matches!(
963            Response::parse(b"STORED"),
964            Err(ParseError::Incomplete)
965        ));
966    }
967
968    #[test]
969    fn test_parse_value_incomplete_data() {
970        // VALUE line complete but data incomplete
971        assert!(matches!(
972            Response::parse(b"VALUE k 0 10\r\nshort\r\nEND\r\n"),
973            Err(ParseError::Incomplete)
974        ));
975    }
976
977    #[test]
978    fn test_parse_value_missing_terminator() {
979        // Data is correct length but missing \r\n terminator
980        assert!(matches!(
981            Response::parse(b"VALUE k 0 5\r\nhelloXXEND\r\n"),
982            Err(ParseError::Protocol("missing data terminator"))
983        ));
984    }
985
986    #[test]
987    fn test_parse_value_invalid_format() {
988        // VALUE line with too few parts
989        assert!(matches!(
990            Response::parse(b"VALUE k\r\nEND\r\n"),
991            Err(ParseError::Protocol("invalid VALUE line"))
992        ));
993    }
994
995    #[test]
996    fn test_parse_value_invalid_flags() {
997        // Non-numeric flags
998        assert!(matches!(
999            Response::parse(b"VALUE k abc 5\r\nhello\r\nEND\r\n"),
1000            Err(ParseError::InvalidNumber)
1001        ));
1002    }
1003
1004    #[test]
1005    fn test_parse_value_invalid_bytes() {
1006        // Non-numeric bytes
1007        assert!(matches!(
1008            Response::parse(b"VALUE k 0 xyz\r\nhello\r\nEND\r\n"),
1009            Err(ParseError::InvalidNumber)
1010        ));
1011    }
1012
1013    #[test]
1014    fn test_parse_value_expected_end() {
1015        // After VALUE data, expect END or another VALUE
1016        assert!(matches!(
1017            Response::parse(b"VALUE k 0 5\r\nhello\r\nSTORED\r\n"),
1018            Err(ParseError::Protocol("expected VALUE or END"))
1019        ));
1020    }
1021
1022    #[test]
1023    fn test_parse_ok() {
1024        let (resp, consumed) = Response::parse(b"OK\r\n").unwrap();
1025        assert_eq!(resp, Response::Ok);
1026        assert_eq!(consumed, 4);
1027    }
1028
1029    #[test]
1030    fn test_encode_ok() {
1031        let mut buf = [0u8; 64];
1032        let len = Response::ok().encode(&mut buf);
1033        assert_eq!(&buf[..len], b"OK\r\n");
1034    }
1035
1036    #[test]
1037    fn test_parse_numeric() {
1038        let (resp, consumed) = Response::parse(b"42\r\n").unwrap();
1039        assert_eq!(resp, Response::Numeric(42));
1040        assert_eq!(consumed, 4);
1041    }
1042
1043    #[test]
1044    fn test_parse_numeric_zero() {
1045        let (resp, consumed) = Response::parse(b"0\r\n").unwrap();
1046        assert_eq!(resp, Response::Numeric(0));
1047        assert_eq!(consumed, 3);
1048    }
1049
1050    #[test]
1051    fn test_parse_numeric_large() {
1052        let (resp, consumed) = Response::parse(b"18446744073709551615\r\n").unwrap();
1053        assert_eq!(resp, Response::Numeric(u64::MAX));
1054        assert_eq!(consumed, 22);
1055    }
1056
1057    #[test]
1058    fn test_encode_numeric() {
1059        let mut buf = [0u8; 64];
1060        let len = Response::numeric(42).encode(&mut buf);
1061        assert_eq!(&buf[..len], b"42\r\n");
1062    }
1063
1064    #[test]
1065    fn test_encode_numeric_zero() {
1066        let mut buf = [0u8; 64];
1067        let len = Response::numeric(0).encode(&mut buf);
1068        assert_eq!(&buf[..len], b"0\r\n");
1069    }
1070
1071    #[test]
1072    fn test_direct_encode_numeric() {
1073        let mut buf = [0u8; 64];
1074        let len = Response::encode_numeric(&mut buf, 12345);
1075        assert_eq!(&buf[..len], b"12345\r\n");
1076    }
1077
1078    #[test]
1079    fn test_is_error_variants() {
1080        assert!(Response::Error.is_error());
1081        assert!(Response::ClientError(b"msg".to_vec()).is_error());
1082        assert!(Response::ServerError(b"msg".to_vec()).is_error());
1083        assert!(!Response::Stored.is_error());
1084        assert!(!Response::NotStored.is_error());
1085        assert!(!Response::Deleted.is_error());
1086        assert!(!Response::NotFound.is_error());
1087        assert!(!Response::Exists.is_error());
1088        assert!(!Response::Ok.is_error());
1089        assert!(!Response::Numeric(42).is_error());
1090        assert!(!Response::Values(vec![]).is_error());
1091        assert!(!Response::Version(b"1.0".to_vec()).is_error());
1092    }
1093
1094    #[test]
1095    fn test_is_miss_variants() {
1096        // Empty values is a miss
1097        assert!(Response::Values(vec![]).is_miss());
1098        // NotFound is a miss
1099        assert!(Response::NotFound.is_miss());
1100        // Non-empty values is not a miss
1101        assert!(
1102            !Response::Values(vec![Value {
1103                key: b"k".to_vec(),
1104                flags: 0,
1105                data: b"v".to_vec(),
1106                cas: None,
1107            }])
1108            .is_miss()
1109        );
1110        // Other responses are not misses
1111        assert!(!Response::Stored.is_miss());
1112        assert!(!Response::Deleted.is_miss());
1113        assert!(!Response::Ok.is_miss());
1114        assert!(!Response::Numeric(0).is_miss());
1115        assert!(!Response::Error.is_miss());
1116    }
1117
1118    #[test]
1119    fn test_is_stored_variants() {
1120        assert!(Response::Stored.is_stored());
1121        assert!(!Response::NotStored.is_stored());
1122        assert!(!Response::Deleted.is_stored());
1123        assert!(!Response::Error.is_stored());
1124    }
1125
1126    #[test]
1127    fn test_encode_not_stored() {
1128        let mut buf = [0u8; 64];
1129        let len = Response::not_stored().encode(&mut buf);
1130        assert_eq!(&buf[..len], b"NOT_STORED\r\n");
1131    }
1132
1133    #[test]
1134    fn test_encode_not_found() {
1135        let mut buf = [0u8; 64];
1136        let len = Response::not_found().encode(&mut buf);
1137        assert_eq!(&buf[..len], b"NOT_FOUND\r\n");
1138    }
1139
1140    #[test]
1141    fn test_encode_exists() {
1142        let mut buf = [0u8; 64];
1143        let len = Response::Exists.encode(&mut buf);
1144        assert_eq!(&buf[..len], b"EXISTS\r\n");
1145    }
1146
1147    #[test]
1148    fn test_encode_error() {
1149        let mut buf = [0u8; 64];
1150        let len = Response::error().encode(&mut buf);
1151        assert_eq!(&buf[..len], b"ERROR\r\n");
1152    }
1153
1154    #[test]
1155    fn test_encode_client_error() {
1156        let mut buf = [0u8; 64];
1157        let len = Response::client_error(b"bad request").encode(&mut buf);
1158        assert_eq!(&buf[..len], b"CLIENT_ERROR bad request\r\n");
1159    }
1160
1161    #[test]
1162    fn test_encode_server_error() {
1163        let mut buf = [0u8; 64];
1164        let len = Response::server_error(b"out of memory").encode(&mut buf);
1165        assert_eq!(&buf[..len], b"SERVER_ERROR out of memory\r\n");
1166    }
1167
1168    #[test]
1169    fn test_encode_version() {
1170        let mut buf = [0u8; 64];
1171        let len = Response::Version(b"1.6.9".to_vec()).encode(&mut buf);
1172        assert_eq!(&buf[..len], b"VERSION 1.6.9\r\n");
1173    }
1174
1175    #[test]
1176    fn test_encode_hit() {
1177        let mut buf = [0u8; 128];
1178        let resp = Response::hit(b"mykey", 42, b"myvalue");
1179        let len = resp.encode(&mut buf);
1180        assert_eq!(&buf[..len], b"VALUE mykey 42 7\r\nmyvalue\r\nEND\r\n");
1181    }
1182
1183    #[test]
1184    fn test_encode_multi_values() {
1185        let mut buf = [0u8; 256];
1186        let resp = Response::Values(vec![
1187            Value {
1188                key: b"k1".to_vec(),
1189                flags: 0,
1190                data: b"v1".to_vec(),
1191                cas: None,
1192            },
1193            Value {
1194                key: b"k2".to_vec(),
1195                flags: 1,
1196                data: b"v2".to_vec(),
1197                cas: None,
1198            },
1199        ]);
1200        let len = resp.encode(&mut buf);
1201        assert_eq!(
1202            &buf[..len],
1203            b"VALUE k1 0 2\r\nv1\r\nVALUE k2 1 2\r\nv2\r\nEND\r\n"
1204        );
1205    }
1206
1207    #[test]
1208    fn test_direct_encode_stored() {
1209        let mut buf = [0u8; 64];
1210        let len = Response::encode_stored(&mut buf);
1211        assert_eq!(&buf[..len], b"STORED\r\n");
1212    }
1213
1214    #[test]
1215    fn test_direct_encode_not_stored() {
1216        let mut buf = [0u8; 64];
1217        let len = Response::encode_not_stored(&mut buf);
1218        assert_eq!(&buf[..len], b"NOT_STORED\r\n");
1219    }
1220
1221    #[test]
1222    fn test_direct_encode_deleted() {
1223        let mut buf = [0u8; 64];
1224        let len = Response::encode_deleted(&mut buf);
1225        assert_eq!(&buf[..len], b"DELETED\r\n");
1226    }
1227
1228    #[test]
1229    fn test_direct_encode_not_found() {
1230        let mut buf = [0u8; 64];
1231        let len = Response::encode_not_found(&mut buf);
1232        assert_eq!(&buf[..len], b"NOT_FOUND\r\n");
1233    }
1234
1235    #[test]
1236    fn test_direct_encode_end() {
1237        let mut buf = [0u8; 64];
1238        let len = Response::encode_end(&mut buf);
1239        assert_eq!(&buf[..len], b"END\r\n");
1240    }
1241
1242    #[test]
1243    fn test_direct_encode_server_error() {
1244        let mut buf = [0u8; 64];
1245        let len = Response::encode_server_error(&mut buf, b"error message");
1246        assert_eq!(&buf[..len], b"SERVER_ERROR error message\r\n");
1247    }
1248
1249    #[test]
1250    fn test_roundtrip_client_error() {
1251        let mut buf = [0u8; 256];
1252        let original = Response::client_error(b"test error");
1253        let len = original.encode(&mut buf);
1254        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1255        assert_eq!(original, parsed);
1256        assert_eq!(len, consumed);
1257    }
1258
1259    #[test]
1260    fn test_roundtrip_server_error() {
1261        let mut buf = [0u8; 256];
1262        let original = Response::server_error(b"test error");
1263        let len = original.encode(&mut buf);
1264        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1265        assert_eq!(original, parsed);
1266        assert_eq!(len, consumed);
1267    }
1268
1269    #[test]
1270    fn test_roundtrip_values() {
1271        let mut buf = [0u8; 256];
1272        let original = Response::hit(b"testkey", 123, b"testvalue");
1273        let len = original.encode(&mut buf);
1274        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1275        assert_eq!(original, parsed);
1276        assert_eq!(len, consumed);
1277    }
1278
1279    #[test]
1280    fn test_value_debug() {
1281        let v = Value {
1282            key: b"k".to_vec(),
1283            flags: 0,
1284            data: b"v".to_vec(),
1285            cas: None,
1286        };
1287        let debug_str = format!("{:?}", v);
1288        assert!(debug_str.contains("Value"));
1289    }
1290
1291    #[test]
1292    fn test_value_clone() {
1293        let v1 = Value {
1294            key: b"k".to_vec(),
1295            flags: 42,
1296            data: b"v".to_vec(),
1297            cas: None,
1298        };
1299        let v2 = v1.clone();
1300        assert_eq!(v1, v2);
1301    }
1302
1303    #[test]
1304    fn test_response_debug() {
1305        let resp = Response::Stored;
1306        let debug_str = format!("{:?}", resp);
1307        assert!(debug_str.contains("Stored"));
1308    }
1309
1310    #[test]
1311    fn test_response_clone() {
1312        let r1 = Response::Stored;
1313        let r2 = r1.clone();
1314        assert_eq!(r1, r2);
1315    }
1316
1317    #[test]
1318    fn test_parse_value_with_flags() {
1319        let data = b"VALUE mykey 12345 5\r\nhello\r\nEND\r\n";
1320        let (resp, _) = Response::parse(data).unwrap();
1321        match resp {
1322            Response::Values(values) => {
1323                assert_eq!(values[0].flags, 12345);
1324            }
1325            _ => panic!("expected Values"),
1326        }
1327    }
1328
1329    #[test]
1330    fn test_find_crlf_edge_cases() {
1331        // \r at end without \n
1332        assert!(Response::parse(b"STORED\r").is_err());
1333    }
1334
1335    #[test]
1336    fn test_parse_value_data_too_large() {
1337        // Value data size exceeding MAX_VALUE_DATA_LEN should be rejected
1338        let data = b"VALUE k 0 18446744073709551615\r\n";
1339        let result = Response::parse(data);
1340        assert!(matches!(
1341            result,
1342            Err(ParseError::Protocol("value data too large"))
1343        ));
1344    }
1345
1346    #[test]
1347    fn test_parse_value_with_cas() {
1348        let data = b"VALUE mykey 0 5 12345\r\nhello\r\nEND\r\n";
1349        let (resp, consumed) = Response::parse(data).unwrap();
1350        assert_eq!(consumed, data.len());
1351        match resp {
1352            Response::Values(values) => {
1353                assert_eq!(values.len(), 1);
1354                assert_eq!(values[0].key, b"mykey");
1355                assert_eq!(values[0].data, b"hello");
1356                assert_eq!(values[0].cas, Some(12345));
1357            }
1358            _ => panic!("expected Values"),
1359        }
1360    }
1361
1362    #[test]
1363    fn test_parse_value_without_cas() {
1364        let data = b"VALUE mykey 0 5\r\nhello\r\nEND\r\n";
1365        let (resp, _) = Response::parse(data).unwrap();
1366        match resp {
1367            Response::Values(values) => {
1368                assert_eq!(values[0].cas, None);
1369            }
1370            _ => panic!("expected Values"),
1371        }
1372    }
1373
1374    #[test]
1375    fn test_roundtrip_value_with_cas() {
1376        let mut buf = [0u8; 256];
1377        let original = Response::Values(vec![Value {
1378            key: b"testkey".to_vec(),
1379            flags: 0,
1380            data: b"testvalue".to_vec(),
1381            cas: Some(98765),
1382        }]);
1383        let len = original.encode(&mut buf);
1384        let (parsed, consumed) = Response::parse(&buf[..len]).unwrap();
1385        assert_eq!(original, parsed);
1386        assert_eq!(len, consumed);
1387    }
1388
1389    #[test]
1390    fn test_parse_multi_value_with_cas() {
1391        let data = b"VALUE k1 0 2 100\r\nv1\r\nVALUE k2 0 2 200\r\nv2\r\nEND\r\n";
1392        let (resp, consumed) = Response::parse(data).unwrap();
1393        assert_eq!(consumed, data.len());
1394        match resp {
1395            Response::Values(values) => {
1396                assert_eq!(values.len(), 2);
1397                assert_eq!(values[0].cas, Some(100));
1398                assert_eq!(values[1].cas, Some(200));
1399            }
1400            _ => panic!("expected Values"),
1401        }
1402    }
1403
1404    // ── ResponseBytes / parse_bytes tests ──────────────────────────────
1405
1406    #[test]
1407    fn test_parse_bytes_stored() {
1408        let data = Bytes::from_static(b"STORED\r\n");
1409        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1410        assert_eq!(resp, ResponseBytes::Stored);
1411        assert_eq!(consumed, 8);
1412    }
1413
1414    #[test]
1415    fn test_parse_bytes_not_stored() {
1416        let data = Bytes::from_static(b"NOT_STORED\r\n");
1417        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1418        assert_eq!(resp, ResponseBytes::NotStored);
1419        assert_eq!(consumed, 12);
1420    }
1421
1422    #[test]
1423    fn test_parse_bytes_deleted() {
1424        let data = Bytes::from_static(b"DELETED\r\n");
1425        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1426        assert_eq!(resp, ResponseBytes::Deleted);
1427        assert_eq!(consumed, 9);
1428    }
1429
1430    #[test]
1431    fn test_parse_bytes_not_found() {
1432        let data = Bytes::from_static(b"NOT_FOUND\r\n");
1433        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1434        assert_eq!(resp, ResponseBytes::NotFound);
1435        assert_eq!(consumed, 11);
1436    }
1437
1438    #[test]
1439    fn test_parse_bytes_exists() {
1440        let data = Bytes::from_static(b"EXISTS\r\n");
1441        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1442        assert_eq!(resp, ResponseBytes::Exists);
1443        assert_eq!(consumed, 8);
1444    }
1445
1446    #[test]
1447    fn test_parse_bytes_end() {
1448        let data = Bytes::from_static(b"END\r\n");
1449        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1450        assert_eq!(resp, ResponseBytes::Values(vec![]));
1451        assert_eq!(consumed, 5);
1452        assert!(resp.is_miss());
1453    }
1454
1455    #[test]
1456    fn test_parse_bytes_ok() {
1457        let data = Bytes::from_static(b"OK\r\n");
1458        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1459        assert_eq!(resp, ResponseBytes::Ok);
1460        assert_eq!(consumed, 4);
1461    }
1462
1463    #[test]
1464    fn test_parse_bytes_error() {
1465        let data = Bytes::from_static(b"ERROR\r\n");
1466        let (resp, _) = ResponseBytes::parse(data).unwrap();
1467        assert!(resp.is_error());
1468    }
1469
1470    #[test]
1471    fn test_parse_bytes_numeric() {
1472        let data = Bytes::from_static(b"42\r\n");
1473        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1474        assert_eq!(resp, ResponseBytes::Numeric(42));
1475        assert_eq!(consumed, 4);
1476    }
1477
1478    #[test]
1479    fn test_parse_bytes_client_error() {
1480        let data = Bytes::from_static(b"CLIENT_ERROR bad request\r\n");
1481        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1482        assert!(resp.is_error());
1483        assert_eq!(consumed, 26);
1484        match resp {
1485            ResponseBytes::ClientError(msg) => assert_eq!(&msg[..], b"bad request"),
1486            _ => panic!("expected ClientError"),
1487        }
1488    }
1489
1490    #[test]
1491    fn test_parse_bytes_server_error() {
1492        let data = Bytes::from_static(b"SERVER_ERROR out of memory\r\n");
1493        let (resp, _) = ResponseBytes::parse(data).unwrap();
1494        assert!(resp.is_error());
1495        match resp {
1496            ResponseBytes::ServerError(msg) => assert_eq!(&msg[..], b"out of memory"),
1497            _ => panic!("expected ServerError"),
1498        }
1499    }
1500
1501    #[test]
1502    fn test_parse_bytes_version() {
1503        let data = Bytes::from_static(b"VERSION 1.6.9\r\n");
1504        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1505        assert_eq!(consumed, 15);
1506        match resp {
1507            ResponseBytes::Version(v) => assert_eq!(&v[..], b"1.6.9"),
1508            _ => panic!("expected Version"),
1509        }
1510    }
1511
1512    #[test]
1513    fn test_parse_bytes_value() {
1514        let data = Bytes::from_static(b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n");
1515        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1516        assert_eq!(consumed, 31);
1517        match resp {
1518            ResponseBytes::Values(values) => {
1519                assert_eq!(values.len(), 1);
1520                assert_eq!(&values[0].key[..], b"mykey");
1521                assert_eq!(values[0].flags, 0);
1522                assert_eq!(&values[0].data[..], b"myvalue");
1523                assert_eq!(values[0].cas, None);
1524            }
1525            _ => panic!("expected Values"),
1526        }
1527    }
1528
1529    #[test]
1530    fn test_parse_bytes_multi_value() {
1531        let raw = b"VALUE key1 0 3\r\nfoo\r\nVALUE key2 0 3\r\nbar\r\nEND\r\n";
1532        let data = Bytes::from_static(raw);
1533        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1534        assert_eq!(consumed, raw.len());
1535        match resp {
1536            ResponseBytes::Values(values) => {
1537                assert_eq!(values.len(), 2);
1538                assert_eq!(&values[0].key[..], b"key1");
1539                assert_eq!(&values[0].data[..], b"foo");
1540                assert_eq!(&values[1].key[..], b"key2");
1541                assert_eq!(&values[1].data[..], b"bar");
1542            }
1543            _ => panic!("expected Values"),
1544        }
1545    }
1546
1547    #[test]
1548    fn test_parse_bytes_value_with_cas() {
1549        let data = Bytes::from_static(b"VALUE mykey 0 5 12345\r\nhello\r\nEND\r\n");
1550        let (resp, consumed) = ResponseBytes::parse(data).unwrap();
1551        assert_eq!(consumed, 35);
1552        match resp {
1553            ResponseBytes::Values(values) => {
1554                assert_eq!(values.len(), 1);
1555                assert_eq!(&values[0].key[..], b"mykey");
1556                assert_eq!(&values[0].data[..], b"hello");
1557                assert_eq!(values[0].cas, Some(12345));
1558            }
1559            _ => panic!("expected Values"),
1560        }
1561    }
1562
1563    #[test]
1564    fn test_parse_bytes_value_with_flags() {
1565        let data = Bytes::from_static(b"VALUE mykey 12345 5\r\nhello\r\nEND\r\n");
1566        let (resp, _) = ResponseBytes::parse(data).unwrap();
1567        match resp {
1568            ResponseBytes::Values(values) => {
1569                assert_eq!(values[0].flags, 12345);
1570            }
1571            _ => panic!("expected Values"),
1572        }
1573    }
1574
1575    #[test]
1576    fn test_parse_bytes_incomplete() {
1577        let data = Bytes::from_static(b"VALUE mykey 0 7\r\nmyval");
1578        assert!(matches!(
1579            ResponseBytes::parse(data),
1580            Err(ParseError::Incomplete)
1581        ));
1582    }
1583
1584    #[test]
1585    fn test_parse_bytes_unknown() {
1586        let data = Bytes::from_static(b"UNKNOWN\r\n");
1587        assert!(matches!(
1588            ResponseBytes::parse(data),
1589            Err(ParseError::Protocol("unknown response"))
1590        ));
1591    }
1592
1593    #[test]
1594    fn test_parse_bytes_zero_copy_slices() {
1595        // Verify that parsed Bytes share the same backing allocation
1596        let raw = b"VALUE mykey 0 7\r\nmyvalue\r\nEND\r\n";
1597        let data = Bytes::copy_from_slice(raw);
1598        let (resp, _) = ResponseBytes::parse(data.clone()).unwrap();
1599        match resp {
1600            ResponseBytes::Values(values) => {
1601                // The key and data should be slices into the original Bytes
1602                assert_eq!(&values[0].key[..], b"mykey");
1603                assert_eq!(&values[0].data[..], b"myvalue");
1604            }
1605            _ => panic!("expected Values"),
1606        }
1607    }
1608
1609    #[test]
1610    fn test_parse_bytes_is_stored() {
1611        assert!(ResponseBytes::Stored.is_stored());
1612        assert!(!ResponseBytes::NotStored.is_stored());
1613    }
1614}