Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: delete NullBulkString and NullArray #10

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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