1use crate::error::ParseError;
14use std::io::Write;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct Value {
19 pub key: Vec<u8>,
20 pub flags: u32,
21 pub data: Vec<u8>,
22 pub cas: Option<u64>,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum Response {
29 Values(Vec<Value>),
31 Stored,
33 NotStored,
35 Deleted,
37 NotFound,
39 Exists,
41 Ok,
43 Numeric(u64),
45 Version(Vec<u8>),
47 Error,
49 ClientError(Vec<u8>),
51 ServerError(Vec<u8>),
53}
54
55impl Response {
56 #[inline]
62 pub fn stored() -> Self {
63 Response::Stored
64 }
65
66 #[inline]
68 pub fn not_stored() -> Self {
69 Response::NotStored
70 }
71
72 #[inline]
74 pub fn deleted() -> Self {
75 Response::Deleted
76 }
77
78 #[inline]
80 pub fn not_found() -> Self {
81 Response::NotFound
82 }
83
84 #[inline]
86 pub fn ok() -> Self {
87 Response::Ok
88 }
89
90 #[inline]
92 pub fn numeric(value: u64) -> Self {
93 Response::Numeric(value)
94 }
95
96 #[inline]
98 pub fn miss() -> Self {
99 Response::Values(vec![])
100 }
101
102 #[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 #[inline]
115 pub fn error() -> Self {
116 Response::Error
117 }
118
119 #[inline]
121 pub fn client_error(msg: &[u8]) -> Self {
122 Response::ClientError(msg.to_vec())
123 }
124
125 #[inline]
127 pub fn server_error(msg: &[u8]) -> Self {
128 Response::ServerError(msg.to_vec())
129 }
130
131 #[inline]
137 pub fn is_error(&self) -> bool {
138 matches!(
139 self,
140 Response::Error | Response::ClientError(_) | Response::ServerError(_)
141 )
142 }
143
144 #[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 #[inline]
156 pub fn is_stored(&self) -> bool {
157 matches!(self, Response::Stored)
158 }
159
160 #[inline]
168 pub fn parse(data: &[u8]) -> Result<(Self, usize), ParseError> {
169 let line_end = find_crlf(data).ok_or(ParseError::Incomplete)?;
171 let line = &data[..line_end];
172
173 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 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 if line.starts_with(b"VALUE ") {
214 return parse_value_response(data);
215 }
216
217 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 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 #[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 #[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 #[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 #[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 #[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 #[inline]
340 pub fn encode_value(buf: &mut [u8], key: &[u8], flags: u32, data: &[u8]) -> usize {
341 let mut pos = 0;
342
343 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 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 buf[pos..pos + 5].copy_from_slice(b"END\r\n");
363 pos + 5
364 }
365
366 #[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 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 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 buf[pos..pos + 5].copy_from_slice(b"END\r\n");
399 pos + 5
400 }
401
402 #[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 #[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 #[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
430fn 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
441fn parse_value_response(data: &[u8]) -> Result<(Response, usize), ParseError> {
443 let mut values = Vec::new();
444 let mut pos = 0;
445
446 loop {
447 let remaining = &data[pos..];
449 let line_end = find_crlf(remaining).ok_or(ParseError::Incomplete)?;
450 let line = &remaining[..line_end];
451
452 if line == b"END" {
454 pos += line_end + 2;
455 break;
456 }
457
458 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 pos += line_end + 2;
479
480 let data_end = pos + bytes;
482 if data.len() < data_end + 2 {
483 return Err(ParseError::Incomplete);
484 }
485
486 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
505fn encode_values(buf: &mut [u8], values: &[Value]) -> usize {
507 let mut pos = 0;
508
509 for value in values {
510 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 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 buf[pos..pos + 5].copy_from_slice(b"END\r\n");
535 pos + 5
536}
537
538fn 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
546fn 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
554const MAX_VALUE_DATA_LEN: usize = 1024 * 1024;
556
557fn 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 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 #[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 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 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 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 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 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 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 assert!(Response::Values(vec![]).is_miss());
899 assert!(Response::NotFound.is_miss());
901 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 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 assert!(Response::parse(b"STORED\r").is_err());
1134 }
1135
1136 #[test]
1137 fn test_parse_value_data_too_large() {
1138 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}