Skip to content

Commit

Permalink
Merge pull request #10 from upupnoah/main
Browse files Browse the repository at this point in the history
refactor: delete NullBulkString and NullArray
  • Loading branch information
upupnoah authored Jul 30, 2024
2 parents 99fceb0 + c0832d7 commit 0e14451
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 67 deletions.
57 changes: 35 additions & 22 deletions src/resp/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RespFrame>);

Expand All @@ -22,6 +24,9 @@ impl RespArray {
// - array: "*<number-of-elements>\r\n<element-1>...<element-n>"
impl RespEncode for RespArray {
fn encode(self) -> Vec<u8> {
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 {
Expand All @@ -35,6 +40,11 @@ impl RespEncode for RespArray {
impl RespDecode for RespArray {
const PREFIX: &'static str = "*";
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
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)?;

Expand All @@ -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<u8> {
b"*-1\r\n".to_vec()
}
}

impl RespDecode for RespNullArray {
const PREFIX: &'static str = "*";
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
extract_fixed_data(buf, "*-1\r\n", "NullArray")?;
Ok(RespNullArray)
}

fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
Ok(4)
}
}
// impl RespEncode for RespNullArray {
// fn encode(self) -> Vec<u8> {
// b"*-1\r\n".to_vec()
// }
// }

// impl RespDecode for RespNullArray {
// const PREFIX: &'static str = "*";
// fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
// extract_fixed_data(buf, "*-1\r\n", "NullArray")?;
// Ok(RespNullArray)
// }

// fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
// Ok(4)
// }
// }

impl Deref for RespArray {
type Target = Vec<RespFrame>;
Expand Down Expand Up @@ -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");
}

Expand All @@ -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(())
}
Expand Down
56 changes: 35 additions & 21 deletions src/resp/bulk_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>); // 单个二进制字符串, 用于存储二进制数据(最大512MB)
Expand All @@ -19,6 +21,9 @@ impl BulkString {
// - bulk string: "$<length>\r\n<data>\r\n"
impl RespEncode for BulkString {
fn encode(self) -> Vec<u8> {
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);
Expand All @@ -30,6 +35,11 @@ impl RespEncode for BulkString {
impl RespDecode for BulkString {
const PREFIX: &'static str = "$";
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
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 {
Expand All @@ -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<u8> {
b"$-1\r\n".to_vec()
}
}

impl RespDecode for RespNullBulkString {
const PREFIX: &'static str = "$";
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
extract_fixed_data(buf, "$-1\r\n", "NullBulkString")?;
Ok(RespNullBulkString)
}

fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
Ok(5)
}
}
// impl RespEncode for RespNullBulkString {
// fn encode(self) -> Vec<u8> {
// b"$-1\r\n".to_vec()
// }
// }

// impl RespDecode for RespNullBulkString {
// const PREFIX: &'static str = "$";
// fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
// extract_fixed_data(buf, "$-1\r\n", "NullBulkString")?;
// Ok(RespNullBulkString)
// }

// fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
// Ok(5)
// }
// }

impl Deref for BulkString {
type Target = Vec<u8>;
Expand Down Expand Up @@ -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");
}

Expand Down Expand Up @@ -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(())
}
Expand Down
59 changes: 35 additions & 24 deletions src/resp/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 的知识点
Expand All @@ -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),
Expand All @@ -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)?;
Expand Down Expand Up @@ -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)?;
Expand All @@ -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)?;
Expand Down

0 comments on commit 0e14451

Please sign in to comment.