Hey @peter-kuchel, for this stage you’ll need a loop within handle_new_conn
.
Example diff that passes tests:
diff --git a/src/main.rs b/src/main.rs
index 5b163fd..62744d3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,72 +1,71 @@
+use std::io::{self, BufRead, BufReader, BufWriter, Cursor, Seek, SeekFrom, Write};
use std::net::{TcpListener, TcpStream};
-use std::io::{self, BufReader, BufWriter, BufRead, Cursor, Seek, SeekFrom, Write};
// use std::time::Duration;
struct ClientResp {
- resps: String
+ resps: String,
}
-fn handle_cmds(cmd: &String, client_resp: &mut ClientResp){
-
+fn handle_cmds(cmd: &String, client_resp: &mut ClientResp) {
let mut _cmd: String = cmd.to_lowercase();
- let cmd_str: &str = _cmd.trim();
+ let cmd_str: &str = _cmd.trim();
match cmd_str {
- "ping"=> {
+ "ping" => {
println!("got ping");
client_resp.resps.push_str("+PONG\r\n");
// let _resp: &str = "+PONG\r\n";
// stream_writer.write(resp.as_bytes()).expect("Write went wrong");
- },
+ }
- _ => { println!("cmd not recognized: {}", cmd_str); }
+ _ => {
+ println!("cmd not recognized: {}", cmd_str);
+ }
}
}
-
-fn parse_client_req(stream_reader: &mut BufReader<TcpStream>, client_resp: &mut ClientResp) -> io::Result<()>{
+fn parse_client_req(
+ stream_reader: &mut BufReader<TcpStream>,
+ client_resp: &mut ClientResp,
+) -> io::Result<()> {
println!("parsing request");
- let req_buf: &[u8] = stream_reader.fill_buf().unwrap();
+ let req_buf: &[u8] = stream_reader.fill_buf().unwrap();
- let mut _line = String::new();
+ let mut _line = String::new();
let mut req_curs = Cursor::new(req_buf);
let cursor_size: usize = req_curs.seek(SeekFrom::End(0)).unwrap() as usize;
req_curs.seek(SeekFrom::Start(0)).unwrap();
-
- let mut curr_pos: usize;
-
- // parse req from the cursor on each new line
- loop{
-
- curr_pos = req_curs.position() as usize;
-
- if curr_pos == cursor_size{
- println!("Finished parsing request");
+
+ let mut curr_pos: usize;
+
+ // parse req from the cursor on each new line
+ loop {
+ curr_pos = req_curs.position() as usize;
+
+ if curr_pos == cursor_size {
+ println!("Finished parsing request");
break;
}
-
- req_curs.read_line(&mut _line).unwrap(); // reading from cursor won't fail
- let line_bytes: &[u8] = _line.as_bytes();
- let _type: u8 = line_bytes[0];
+ req_curs.read_line(&mut _line).unwrap(); // reading from cursor won't fail
+ let line_bytes: &[u8] = _line.as_bytes();
+ let _type: u8 = line_bytes[0];
match _type {
- // Bulk String
+ // Bulk String
0x24 => {
-
- _line.clear();
- req_curs.read_line(&mut _line).unwrap();
+ _line.clear();
+ req_curs.read_line(&mut _line).unwrap();
_line = _line.replace("\r\n", "");
handle_cmds(&_line, client_resp);
+ }
- },
-
- // Array
+ // Array
0x2a => {
// get array size
}
@@ -80,51 +79,53 @@ fn parse_client_req(stream_reader: &mut BufReader<TcpStream>, client_resp: &mut
}
Ok(())
-
}
-fn handle_new_conn(stream: TcpStream) -> io::Result<()>{
+fn handle_new_conn(stream: TcpStream) -> io::Result<()> {
+ let write_stream: TcpStream = stream
+ .try_clone()
+ .expect("cloning the client tcp stream failed");
- let write_stream: TcpStream = stream.try_clone().expect("cloning the client tcp stream failed");
+ loop {
+ let mut client_resp = ClientResp {
+ resps: String::with_capacity(1 << 8),
+ };
+ let mut stream_reader: BufReader<TcpStream> = BufReader::new(stream.try_clone().unwrap());
- let mut client_resp = ClientResp { resps: String::with_capacity( 1 << 8 ), };
- let mut stream_reader: BufReader<TcpStream> = BufReader::new(stream);
-
+ let _resp_res = parse_client_req(&mut stream_reader, &mut client_resp);
- let _resp_res = parse_client_req( &mut stream_reader, &mut client_resp);
+ // handle sending everything back to the client now
+ {
+ let mut stream_writer: BufWriter<TcpStream> =
+ BufWriter::new(write_stream.try_clone().unwrap());
+ let mut resp_curs: Cursor<String> = Cursor::new(client_resp.resps);
+ let curs_size: u64 = resp_curs.seek(SeekFrom::End(0)).unwrap();
+ resp_curs.seek(SeekFrom::Start(0)).unwrap();
- // handle sending everything back to the client now
- {
- let mut stream_writer: BufWriter<TcpStream> = BufWriter::new(write_stream);
- let mut resp_curs: Cursor<String> = Cursor::new(client_resp.resps);
- let curs_size: u64 = resp_curs.seek(SeekFrom::End(0)).unwrap();
- resp_curs.seek(SeekFrom::Start(0)).unwrap();
+ let mut resp_line = String::new();
+ while curs_size != resp_curs.position() {
+ resp_curs.read_line(&mut resp_line)?;
- let mut resp_line = String::new();
-
- while curs_size != resp_curs.position() {
-
- resp_curs.read_line(&mut resp_line)?;
+ stream_writer.write(resp_line.as_bytes())?;
+ stream_writer.flush()?;
+ resp_line.clear();
+ }
+ }
- stream_writer.write(resp_line.as_bytes())?;
- stream_writer.flush()?;
- resp_line.clear();
+ if _resp_res.is_err() {
+ break;
}
-
}
-
- Ok(())
-
+ Ok(())
}
fn main() -> io::Result<()> {
-
println!("Logs from your program will appear here!");
let listener = TcpListener::bind("127.0.0.1:6379").unwrap();
-
+
for stream in listener.incoming() {
match stream {
Ok(_stream) => {
(Please ignore the formatting stuff, rustfmt ended up changing a lot of lines)
The important change is the loop within handle_new_conn
.