diff --git a/src/resp/array.rs b/src/resp/array.rs index a83280a..240aab5 100644 --- a/src/resp/array.rs +++ b/src/resp/array.rs @@ -3,10 +3,12 @@ use std::ops::Deref; use bytes::{Buf, BytesMut}; use super::{ - calc_total_length, extract_fixed_data, parse_length, RespDecode, RespEncode, RespError, - RespFrame, BUF_CAP, CRLF_LEN, + calc_total_length, parse_length, RespDecode, RespEncode, RespError, RespFrame, BUF_CAP, + CRLF_LEN, }; +const NULL_ARRAY: &[u8] = b"*-1\r\n"; + #[derive(Debug, Clone, PartialEq)] pub struct RespArray(pub(crate) Vec); @@ -22,6 +24,9 @@ impl RespArray { // - array: "*\r\n..." impl RespEncode for RespArray { fn encode(self) -> Vec { + if self.is_empty() { + return NULL_ARRAY.to_vec(); + } let mut buf = Vec::with_capacity(BUF_CAP); buf.extend_from_slice(&format!("*{}\r\n", self.len()).into_bytes()); for frame in self.0 { @@ -35,6 +40,11 @@ impl RespEncode for RespArray { impl RespDecode for RespArray { const PREFIX: &'static str = "*"; fn decode(buf: &mut BytesMut) -> Result { + if buf.starts_with(NULL_ARRAY) { + buf.advance(NULL_ARRAY.len()); + return Ok(RespArray::new(vec![])); + } + let (end, len) = parse_length(buf, Self::PREFIX)?; let total_len = calc_total_length(buf, end, len, Self::PREFIX)?; @@ -58,24 +68,25 @@ impl RespDecode for RespArray { } } +// NOTE: refactor -> delete RespNullArray, add NULL_ARRAY // - null array: "*-1\r\n" -impl RespEncode for RespNullArray { - fn encode(self) -> Vec { - b"*-1\r\n".to_vec() - } -} - -impl RespDecode for RespNullArray { - const PREFIX: &'static str = "*"; - fn decode(buf: &mut BytesMut) -> Result { - extract_fixed_data(buf, "*-1\r\n", "NullArray")?; - Ok(RespNullArray) - } - - fn expect_length(_buf: &[u8]) -> Result { - Ok(4) - } -} +// impl RespEncode for RespNullArray { +// fn encode(self) -> Vec { +// b"*-1\r\n".to_vec() +// } +// } + +// impl RespDecode for RespNullArray { +// const PREFIX: &'static str = "*"; +// fn decode(buf: &mut BytesMut) -> Result { +// extract_fixed_data(buf, "*-1\r\n", "NullArray")?; +// Ok(RespNullArray) +// } + +// fn expect_length(_buf: &[u8]) -> Result { +// Ok(4) +// } +// } impl Deref for RespArray { type Target = Vec; @@ -107,7 +118,8 @@ mod tests { #[test] fn test_null_array_encode() { - let frame: RespFrame = RespNullArray.into(); + // let frame: RespFrame = RespNullArray.into(); + let frame: RespFrame = RespArray::new(vec![]).into(); assert_eq!(frame.encode(), b"*-1\r\n"); } @@ -116,8 +128,9 @@ mod tests { let mut buf = BytesMut::new(); buf.extend_from_slice(b"*-1\r\n"); - let frame = RespNullArray::decode(&mut buf)?; - assert_eq!(frame, RespNullArray); + // let frame = RespNullArray::decode(&mut buf)?; + let frame = RespArray::decode(&mut buf)?; + assert_eq!(frame, RespArray::new(vec![])); Ok(()) } diff --git a/src/resp/bulk_string.rs b/src/resp/bulk_string.rs index 1438f83..d25ab7b 100644 --- a/src/resp/bulk_string.rs +++ b/src/resp/bulk_string.rs @@ -2,7 +2,9 @@ use std::ops::Deref; use bytes::{Buf, BytesMut}; -use super::{extract_fixed_data, parse_length, RespDecode, RespEncode, RespError, CRLF_LEN}; +use super::{parse_length, RespDecode, RespEncode, RespError, CRLF_LEN}; + +const NULL_BULK_STRING: &[u8] = b"$-1\r\n"; #[derive(Debug, Clone, PartialEq, Eq)] pub struct BulkString(pub(crate) Vec); // 单个二进制字符串, 用于存储二进制数据(最大512MB) @@ -19,6 +21,9 @@ impl BulkString { // - bulk string: "$\r\n\r\n" impl RespEncode for BulkString { fn encode(self) -> Vec { + if self.is_empty() { + return NULL_BULK_STRING.to_vec(); + } let mut buf = Vec::with_capacity(self.len() + 16); buf.extend_from_slice(&format!("${}\r\n", self.len()).into_bytes()); buf.extend_from_slice(&self); @@ -30,6 +35,11 @@ impl RespEncode for BulkString { impl RespDecode for BulkString { const PREFIX: &'static str = "$"; fn decode(buf: &mut BytesMut) -> Result { + if buf.starts_with(NULL_BULK_STRING) { + buf.advance(NULL_BULK_STRING.len()); // advance the buffer + return Ok(BulkString::new(vec![])); + } + let (end, len) = parse_length(buf, Self::PREFIX)?; let remained = &buf[end + CRLF_LEN..]; if remained.len() < len + CRLF_LEN { @@ -48,24 +58,25 @@ impl RespDecode for BulkString { } } +// NOTE: refactor -> delete RespNullBulkString, add NULL_BULK_STRING // - null bulk string: "$-1\r\n" -impl RespEncode for RespNullBulkString { - fn encode(self) -> Vec { - b"$-1\r\n".to_vec() - } -} - -impl RespDecode for RespNullBulkString { - const PREFIX: &'static str = "$"; - fn decode(buf: &mut BytesMut) -> Result { - extract_fixed_data(buf, "$-1\r\n", "NullBulkString")?; - Ok(RespNullBulkString) - } - - fn expect_length(_buf: &[u8]) -> Result { - Ok(5) - } -} +// impl RespEncode for RespNullBulkString { +// fn encode(self) -> Vec { +// b"$-1\r\n".to_vec() +// } +// } + +// impl RespDecode for RespNullBulkString { +// const PREFIX: &'static str = "$"; +// fn decode(buf: &mut BytesMut) -> Result { +// extract_fixed_data(buf, "$-1\r\n", "NullBulkString")?; +// Ok(RespNullBulkString) +// } + +// fn expect_length(_buf: &[u8]) -> Result { +// Ok(5) +// } +// } impl Deref for BulkString { type Target = Vec; @@ -120,7 +131,8 @@ mod tests { #[test] fn test_null_bulk_string_encode() { - let frame: RespFrame = RespNullBulkString.into(); + // let frame: RespFrame = RespNullBulkString.into(); + let frame: RespFrame = BulkString::new(vec![]).into(); assert_eq!(frame.encode(), b"$-1\r\n"); } @@ -148,8 +160,10 @@ mod tests { let mut buf = BytesMut::new(); buf.extend_from_slice(b"$-1\r\n"); - let frame = RespNullBulkString::decode(&mut buf)?; - assert_eq!(frame, RespNullBulkString); + // let frame = RespNullBulkString::decode(&mut buf)?; + // assert_eq!(frame, RespNullBulkString); + let ret = BulkString::decode(&mut buf)?; + assert_eq!(ret, BulkString::new(vec![])); Ok(()) } diff --git a/src/resp/frame.rs b/src/resp/frame.rs index 1a1dd72..54c7a0b 100644 --- a/src/resp/frame.rs +++ b/src/resp/frame.rs @@ -2,8 +2,8 @@ use bytes::BytesMut; use enum_dispatch::enum_dispatch; use super::{ - BulkString, RespArray, RespDecode, RespError, RespMap, RespNull, RespNullArray, - RespNullBulkString, RespSet, SimpleError, SimpleString, + BulkString, RespArray, RespDecode, RespError, RespMap, RespNull, RespSet, SimpleError, + SimpleString, }; // 关于 enum 的知识点 @@ -21,9 +21,9 @@ pub enum RespFrame { Error(SimpleError), Integer(i64), BulkString(BulkString), - NullBulkString(RespNullBulkString), + // NullBulkString(RespNullBulkString), Array(RespArray), - NullArray(RespNullArray), + // NullArray(RespNullArray), Null(RespNull), Boolean(bool), Double(f64), @@ -49,27 +49,36 @@ impl RespDecode for RespFrame { let frame = i64::decode(buf)?; Ok(frame.into()) } + // NOTE: refactor -> delete NullBulkString and NullArray + // Some(b'$') => { + // // try null bulk string first + // match RespNullBulkString::decode(buf) { + // Ok(frame) => Ok(frame.into()), + // Err(RespError::NotComplete) => Err(RespError::NotComplete), + // Err(_) => { + // let frame = BulkString::decode(buf)?; + // Ok(frame.into()) + // } + // } + // } + // Some(b'*') => { + // // try null array first + // match RespNullArray::decode(buf) { + // Ok(frame) => Ok(frame.into()), + // Err(RespError::NotComplete) => Err(RespError::NotComplete), + // Err(_) => { + // let frame = RespArray::decode(buf)?; + // Ok(frame.into()) + // } + // } + // } Some(b'$') => { - // try null bulk string first - match RespNullBulkString::decode(buf) { - Ok(frame) => Ok(frame.into()), - Err(RespError::NotComplete) => Err(RespError::NotComplete), - Err(_) => { - let frame = BulkString::decode(buf)?; - Ok(frame.into()) - } - } + let frame = BulkString::decode(buf)?; + Ok(frame.into()) } Some(b'*') => { - // try null array first - match RespNullArray::decode(buf) { - Ok(frame) => Ok(frame.into()), - Err(RespError::NotComplete) => Err(RespError::NotComplete), - Err(_) => { - let frame = RespArray::decode(buf)?; - Ok(frame.into()) - } - } + let frame = RespArray::decode(buf)?; + Ok(frame.into()) } Some(b'_') => { let frame = RespNull::decode(buf)?; @@ -161,7 +170,8 @@ mod tests { buf.extend_from_slice(b"$-1\r\n"); let frame = RespFrame::decode(&mut buf)?; - assert_eq!(frame, RespNullBulkString.into()); + // assert_eq!(frame, RespNullBulkString.into()); + assert_eq!(frame, BulkString::new(vec![]).into()); buf.extend_from_slice(b"*2\r\n$4\r\necho\r\n$5\r\nhello\r\n"); let frame = RespFrame::decode(&mut buf)?; @@ -176,7 +186,8 @@ mod tests { buf.extend_from_slice(b"*-1\r\n"); let frame = RespFrame::decode(&mut buf)?; - assert_eq!(frame, RespNullArray.into()); + // assert_eq!(frame, RespNullArray.into()); + assert_eq!(frame, RespArray::new(vec![]).into()); buf.extend_from_slice(b"_\r\n"); let frame = RespFrame::decode(&mut buf)?;