memcached_protocal/command/
store_command.rs1use std::io::BufRead;
2
3use ::error::Result;
4use ::error::ErrorKind;
5use ::byte_utils::read_until;
6
7#[derive(Debug, PartialEq)]
8pub struct StoreCommand {
9 pub command_name: String,
10 pub key: String,
11 pub flags: u16,
12 pub exptime: u32,
13 pub bytes: u64,
14 pub cas_unique: Option<u64>,
15 pub noreply: Option<String>,
16 pub data_block: Vec<u8>,
17}
18
19
20impl StoreCommand {
21 pub fn parse<R: BufRead>(reader: &mut R) -> Result<StoreCommand> {
22 let cmd_line = try!(read_until(reader, "\r\n"));
23 let cmd_str = try!(String::from_utf8(cmd_line));
24 let segments = cmd_str.split_whitespace().collect::<Vec<&str>>();
25 let length = segments.len();
26 if length < 1 {
27 return Err(ErrorKind::ClientError("wrong size of params".to_owned()).into());
28 }
29 let cmd = segments[0];
30 let is_cas = match cmd {
31 "set" => false,
32 "add" => false,
33 "replace" => false,
34 "append" => false,
35 "prepend" => false,
36 "cas" => true,
37 _ => return Err(ErrorKind::ClientError("wrong size of params".to_owned()).into()),
38 };
39
40 match is_cas {
41 true if 6 <= length && length <= 7 => (),
42 false if 5 <= length && length <= 6 => (),
43 _ => return Err(ErrorKind::ClientError("wrong size of params".to_owned()).into()),
44 }
45
46 let bytes = try!(segments[4].parse::<u64>());
47 let cas_unique = if is_cas {
48 Some(try!(segments[5].parse::<u64>()))
49 } else {
50 None
51 };
52
53 let noreply = match is_cas {
54 true if length == 7 => Some(segments[6].to_owned()),
55 false if length == 6 => Some(segments[5].to_owned()),
56 _ => None,
57 };
58
59 let mut data_block = vec![0; bytes as usize];
60 let _ = try!(reader.read_exact(&mut data_block));
61 if try!(read_until(reader, "\r\n")) != vec![] {
62 return Err(ErrorKind::ClientError("error data block".to_owned()).into());
63 }
64
65 Ok(StoreCommand {
66 command_name: cmd.to_owned(),
67 key: segments[1].to_owned(),
68 flags: try!(segments[2].parse::<u16>()),
69 exptime: try!(segments[3].parse::<u32>()),
70 bytes: bytes,
71 cas_unique: cas_unique,
72 noreply: noreply,
73 data_block: data_block,
74 })
75 }
76}