1use super::Frame;
2use bytes::Bytes;
3use std::{fmt, str, vec};
4
5#[derive(Debug)]
6pub struct Parse {
7 parts: vec::IntoIter<Frame>,
8}
9
10#[derive(Debug)]
11pub enum ParseError {
12 EndOfStream,
13 Other(crate::Error),
14}
15
16impl Parse {
17 pub fn new(frame: Frame) -> Result<Parse, ParseError> {
18 let array = match frame {
19 Frame::Array(array) => array,
20 frame => return Err(format!("protocol error; expected array, got {:?}", frame).into()),
21 };
22
23 Ok(Parse { parts: array.into_iter() })
24 }
25
26 fn next(&mut self) -> Result<Frame, ParseError> { self.parts.next().ok_or(ParseError::EndOfStream) }
27
28 pub fn next_string(&mut self) -> Result<String, ParseError> {
29 match self.next()? {
30 Frame::Simple(s) => Ok(s),
31 Frame::Bulk(data) => str::from_utf8(&data[..]).map(|s| s.to_string()).map_err(|_| "protocol error; invalid string".into()),
32 frame => Err(format!("protocol error; expected simple frame or bulk frame, got {:?}", frame).into()),
33 }
34 }
35
36 pub fn next_bytes(&mut self) -> Result<Bytes, ParseError> {
37 match self.next()? {
38 Frame::Simple(s) => Ok(Bytes::from(s.into_bytes())),
39 Frame::Bulk(data) => Ok(data),
40 frame => Err(format!("protocol error; expected simple frame or bulk frame, got {:?}", frame).into()),
41 }
42 }
43
44 pub fn next_int(&mut self) -> Result<u64, ParseError> {
45 use atoi::atoi;
46 const MSG: &str = "protocol error; invalid number";
47
48 match self.next()? {
49 Frame::Integer(v) => Ok(v),
50 Frame::Simple(data) => atoi::<u64>(data.as_bytes()).ok_or_else(|| MSG.into()),
51 Frame::Bulk(data) => atoi::<u64>(&data).ok_or_else(|| MSG.into()),
52 frame => Err(format!("protocol error; expected int frame but got {:?}", frame).into()),
53 }
54 }
55
56 pub fn finish(&mut self) -> Result<(), ParseError> {
57 if self.parts.next().is_none() {
58 Ok(())
59 } else {
60 Err("protocol error; expected end of frame, but there was more".into())
61 }
62 }
63}
64
65impl From<String> for ParseError {
66 fn from(src: String) -> ParseError { ParseError::Other(src.into()) }
67}
68
69impl From<&str> for ParseError {
70 fn from(src: &str) -> ParseError { src.to_string().into() }
71}
72
73impl fmt::Display for ParseError {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match self {
76 ParseError::EndOfStream => "protocol error; unexpected end of stream".fmt(f),
77 ParseError::Other(err) => err.fmt(f),
78 }
79 }
80}
81
82impl std::error::Error for ParseError {}