use std::io::{BufRead, Read, Write};
use std::net::TcpStream;
use std::str::FromStr;
use bufstream::BufStream;
use crate::command::Status;
use crate::error::{BeanstalkcError, BeanstalkcResult};
use crate::response::Response;
#[derive(Debug)]
pub struct Request<'b> {
stream: &'b mut BufStream<TcpStream>,
}
impl<'b> Request<'b> {
pub fn new(stream: &'b mut BufStream<TcpStream>) -> Self {
Request { stream }
}
pub fn send(&mut self, message: &[u8]) -> BeanstalkcResult<Response> {
let _ = self.stream.write(message)?;
self.stream.flush()?;
let mut line = String::new();
self.stream.read_line(&mut line)?;
if line.trim().is_empty() {
return Err(BeanstalkcError::UnexpectedResponse(
"empty response".to_string(),
));
}
let line_parts: Vec<_> = line.split_whitespace().collect();
let mut response = Response::default();
response.status = Status::from_str(line_parts.first().unwrap_or(&""))?;
response.params = line_parts[1..].iter().map(|&x| x.to_string()).collect();
let body_byte_count = match response.status {
Status::Ok => response.get_int_param(0)?,
Status::Reserved => response.get_int_param(1)?,
Status::Found => response.get_int_param(1)?,
_ => {
return Ok(response);
}
} as usize;
let mut tmp: Vec<u8> = vec![0; body_byte_count + 2]; let body = &mut tmp[..];
self.stream.read_exact(body)?;
tmp.truncate(body_byte_count);
response.body = Some(tmp);
Ok(response)
}
}