in src/protocol/resp/src/request/mod.rs [35:115]
fn parse(&self, buffer: &[u8]) -> Result<ParseOk<Request>, Error> {
// we have two different parsers, one for RESP and one for inline
// both require that there's at least one character in the buffer
if buffer.is_empty() {
return Err(Error::from(ErrorKind::WouldBlock));
}
let (message, consumed) = if matches!(buffer[0], b'*' | b'+' | b'-' | b':' | b'$') {
self.message_parser.parse(buffer).map(|v| {
let c = v.consumed();
(v.into_inner(), c)
})?
} else {
let mut remaining = buffer;
let mut message = Vec::new();
while let Ok((r, string)) = string(remaining) {
message.push(Message::BulkString(BulkString {
inner: Some(Arc::new(string.to_owned().into_boxed_slice())),
}));
remaining = r;
if let Ok((r, _)) = space1(remaining) {
remaining = r;
} else {
break;
}
}
if &remaining[0..2] != b"\r\n" {
return Err(Error::from(ErrorKind::WouldBlock));
}
let message = Message::Array(Array {
inner: Some(message),
});
let consumed = (buffer.len() - remaining.len()) + 2;
(message, consumed)
};
match &message {
Message::Array(array) => {
if array.inner.is_none() {
return Err(Error::new(ErrorKind::Other, "malformed command"));
}
let array = array.inner.as_ref().unwrap();
if array.is_empty() {
return Err(Error::new(ErrorKind::Other, "malformed command"));
}
match &array[0] {
Message::BulkString(c) => match c.inner.as_ref().map(|v| v.as_ref().as_ref()) {
Some(b"badd") | Some(b"BADD") => {
BAddRequest::try_from(message).map(Request::from)
}
Some(b"get") | Some(b"GET") => {
GetRequest::try_from(message).map(Request::from)
}
Some(b"set") | Some(b"SET") => {
SetRequest::try_from(message).map(Request::from)
}
_ => Err(Error::new(ErrorKind::Other, "unknown command")),
},
_ => {
// all valid commands are encoded as a bulk string
Err(Error::new(ErrorKind::Other, "malformed command"))
}
}
}
_ => {
// all valid requests are arrays
Err(Error::new(ErrorKind::Other, "malformed command"))
}
}
.map(|v| ParseOk::new(v, consumed))
}