Skip to content

Commit a4a9134

Browse files
committed
refactor: encode/decode
1 parent 77f4a1f commit a4a9134

File tree

16 files changed

+1166
-816
lines changed

16 files changed

+1166
-816
lines changed

dump.rdb

134 Bytes
Binary file not shown.

src/cmd/map.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ impl TryFrom<RespArray> for Set {
5656

5757
#[cfg(test)]
5858
mod tests {
59-
use super::*;
6059
use crate::RespDecode;
60+
61+
use super::*;
6162
use anyhow::Result;
6263
use bytes::BytesMut;
6364

src/resp/array.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
use std::ops::Deref;
2+
3+
use bytes::{Buf, BytesMut};
4+
5+
use super::{
6+
calc_total_length, extract_fixed_data, parse_length, RespDecode, RespEncode, RespError,
7+
RespFrame, BUF_CAP, CRLF_LEN,
8+
};
9+
10+
#[derive(Debug, Clone, PartialEq)]
11+
pub struct RespArray(pub(crate) Vec<RespFrame>);
12+
13+
#[derive(Debug, Clone, PartialEq, Eq)]
14+
pub struct RespNullArray;
15+
16+
impl RespArray {
17+
pub fn new(s: impl Into<Vec<RespFrame>>) -> Self {
18+
RespArray(s.into())
19+
}
20+
}
21+
22+
// - array: "*<number-of-elements>\r\n<element-1>...<element-n>"
23+
impl RespEncode for RespArray {
24+
fn encode(self) -> Vec<u8> {
25+
let mut buf = Vec::with_capacity(BUF_CAP);
26+
buf.extend_from_slice(&format!("*{}\r\n", self.len()).into_bytes());
27+
for frame in self.0 {
28+
buf.extend_from_slice(&frame.encode());
29+
}
30+
buf
31+
}
32+
}
33+
34+
// - array: "*<number-of-elements>\r\n<element-1>...<element-n>"
35+
impl RespDecode for RespArray {
36+
const PREFIX: &'static str = "*";
37+
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
38+
let (end, len) = parse_length(buf, Self::PREFIX)?;
39+
let total_len = calc_total_length(buf, end, len, Self::PREFIX)?;
40+
41+
if buf.len() < total_len {
42+
return Err(RespError::NotComplete);
43+
}
44+
45+
buf.advance(end + CRLF_LEN);
46+
47+
let mut frames = Vec::with_capacity(len);
48+
for _ in 0..len {
49+
frames.push(RespFrame::decode(buf)?);
50+
}
51+
52+
Ok(RespArray::new(frames))
53+
}
54+
55+
fn expect_length(buf: &[u8]) -> Result<usize, RespError> {
56+
let (end, len) = parse_length(buf, Self::PREFIX)?;
57+
calc_total_length(buf, end, len, Self::PREFIX)
58+
}
59+
}
60+
61+
// - null array: "*-1\r\n"
62+
impl RespEncode for RespNullArray {
63+
fn encode(self) -> Vec<u8> {
64+
b"*-1\r\n".to_vec()
65+
}
66+
}
67+
68+
impl RespDecode for RespNullArray {
69+
const PREFIX: &'static str = "*";
70+
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
71+
extract_fixed_data(buf, "*-1\r\n", "NullArray")?;
72+
Ok(RespNullArray)
73+
}
74+
75+
fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
76+
Ok(4)
77+
}
78+
}
79+
80+
impl Deref for RespArray {
81+
type Target = Vec<RespFrame>;
82+
83+
fn deref(&self) -> &Self::Target {
84+
&self.0
85+
}
86+
}
87+
88+
#[cfg(test)]
89+
mod tests {
90+
use super::*;
91+
use crate::BulkString;
92+
use anyhow::Result;
93+
94+
#[test]
95+
fn test_array_encode() {
96+
let frame: RespFrame = RespArray::new(vec![
97+
BulkString::new("set".to_string()).into(),
98+
BulkString::new("hello".to_string()).into(),
99+
BulkString::new("world".to_string()).into(),
100+
])
101+
.into();
102+
assert_eq!(
103+
&frame.encode(),
104+
b"*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n"
105+
);
106+
}
107+
108+
#[test]
109+
fn test_null_array_encode() {
110+
let frame: RespFrame = RespNullArray.into();
111+
assert_eq!(frame.encode(), b"*-1\r\n");
112+
}
113+
114+
#[test]
115+
fn test_null_array_decode() -> Result<()> {
116+
let mut buf = BytesMut::new();
117+
buf.extend_from_slice(b"*-1\r\n");
118+
119+
let frame = RespNullArray::decode(&mut buf)?;
120+
assert_eq!(frame, RespNullArray);
121+
122+
Ok(())
123+
}
124+
125+
#[test]
126+
fn test_array_decode() -> Result<()> {
127+
let mut buf = BytesMut::new();
128+
buf.extend_from_slice(b"*2\r\n$3\r\nset\r\n$5\r\nhello\r\n");
129+
130+
let frame = RespArray::decode(&mut buf)?;
131+
assert_eq!(frame, RespArray::new([b"set".into(), b"hello".into()]));
132+
133+
buf.extend_from_slice(b"*2\r\n$3\r\nset\r\n");
134+
let ret = RespArray::decode(&mut buf);
135+
assert_eq!(ret.unwrap_err(), RespError::NotComplete);
136+
137+
buf.extend_from_slice(b"$5\r\nhello\r\n");
138+
let frame = RespArray::decode(&mut buf)?;
139+
assert_eq!(frame, RespArray::new([b"set".into(), b"hello".into()]));
140+
141+
Ok(())
142+
}
143+
}

src/resp/bool.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use bytes::BytesMut;
2+
3+
use super::{extract_fixed_data, RespDecode, RespEncode, RespError};
4+
5+
// - boolean: "#<t|f>\r\n"
6+
impl RespEncode for bool {
7+
fn encode(self) -> Vec<u8> {
8+
// if self {
9+
// b"#t\r\n".to_vec()
10+
// } else {
11+
// b"#f\r\n".to_vec()
12+
// }
13+
format!("#{}\r\n", if self { "t" } else { "f" }).into_bytes()
14+
}
15+
}
16+
17+
// - boolean: "#<t|f>\r\n"
18+
impl RespDecode for bool {
19+
const PREFIX: &'static str = "#";
20+
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
21+
match extract_fixed_data(buf, "#t\r\n", "Bool") {
22+
Ok(_) => Ok(true),
23+
Err(RespError::NotComplete) => Err(RespError::NotComplete),
24+
Err(_) => match extract_fixed_data(buf, "#f\r\n", "Bool") {
25+
Ok(_) => Ok(false),
26+
Err(e) => Err(e),
27+
},
28+
}
29+
}
30+
31+
fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
32+
Ok(4)
33+
}
34+
}
35+
36+
#[cfg(test)]
37+
mod tests {
38+
use crate::RespFrame;
39+
40+
use super::*;
41+
use anyhow::Result;
42+
use bytes::BufMut;
43+
44+
#[test]
45+
fn test_boolean_encode() {
46+
let frame: RespFrame = true.into();
47+
assert_eq!(frame.encode(), b"#t\r\n");
48+
49+
let frame: RespFrame = false.into();
50+
assert_eq!(frame.encode(), b"#f\r\n");
51+
}
52+
53+
#[test]
54+
fn test_boolean_decode() -> Result<()> {
55+
let mut buf = BytesMut::new();
56+
buf.extend_from_slice(b"#t\r\n");
57+
58+
let frame = bool::decode(&mut buf)?;
59+
assert!(frame);
60+
61+
buf.extend_from_slice(b"#f\r\n");
62+
63+
let frame = bool::decode(&mut buf)?;
64+
assert!(!frame);
65+
66+
buf.extend_from_slice(b"#f\r");
67+
let ret = bool::decode(&mut buf);
68+
assert_eq!(ret.unwrap_err(), RespError::NotComplete);
69+
70+
buf.put_u8(b'\n');
71+
let frame = bool::decode(&mut buf)?;
72+
assert!(!frame);
73+
74+
Ok(())
75+
}
76+
}

src/resp/bulk_string.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
use std::ops::Deref;
2+
3+
use bytes::{Buf, BytesMut};
4+
5+
use super::{extract_fixed_data, parse_length, RespDecode, RespEncode, RespError, CRLF_LEN};
6+
7+
#[derive(Debug, Clone, PartialEq, Eq)]
8+
pub struct BulkString(pub(crate) Vec<u8>); // 单个二进制字符串, 用于存储二进制数据(最大512MB)
9+
10+
#[derive(Debug, Clone, PartialEq, Eq)]
11+
pub struct RespNullBulkString;
12+
13+
impl BulkString {
14+
pub fn new(s: impl Into<Vec<u8>>) -> Self {
15+
BulkString(s.into())
16+
}
17+
}
18+
19+
// - bulk string: "$<length>\r\n<data>\r\n"
20+
impl RespEncode for BulkString {
21+
fn encode(self) -> Vec<u8> {
22+
let mut buf = Vec::with_capacity(self.len() + 16);
23+
buf.extend_from_slice(&format!("${}\r\n", self.len()).into_bytes());
24+
buf.extend_from_slice(&self);
25+
buf.extend_from_slice(b"\r\n");
26+
buf
27+
}
28+
}
29+
// - bulk string: "$<length>\r\n<data>\r\n"
30+
impl RespDecode for BulkString {
31+
const PREFIX: &'static str = "$";
32+
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
33+
let (end, len) = parse_length(buf, Self::PREFIX)?;
34+
let remained = &buf[end + CRLF_LEN..];
35+
if remained.len() < len + CRLF_LEN {
36+
return Err(RespError::NotComplete);
37+
}
38+
39+
buf.advance(end + CRLF_LEN);
40+
41+
let data = buf.split_to(len + CRLF_LEN);
42+
Ok(BulkString::new(data[..len].to_vec()))
43+
}
44+
45+
fn expect_length(buf: &[u8]) -> Result<usize, RespError> {
46+
let (end, len) = parse_length(buf, Self::PREFIX)?;
47+
Ok(end + CRLF_LEN + len + CRLF_LEN)
48+
}
49+
}
50+
51+
// - null bulk string: "$-1\r\n"
52+
impl RespEncode for RespNullBulkString {
53+
fn encode(self) -> Vec<u8> {
54+
b"$-1\r\n".to_vec()
55+
}
56+
}
57+
58+
impl RespDecode for RespNullBulkString {
59+
const PREFIX: &'static str = "$";
60+
fn decode(buf: &mut BytesMut) -> Result<Self, RespError> {
61+
extract_fixed_data(buf, "$-1\r\n", "NullBulkString")?;
62+
Ok(RespNullBulkString)
63+
}
64+
65+
fn expect_length(_buf: &[u8]) -> Result<usize, RespError> {
66+
Ok(5)
67+
}
68+
}
69+
70+
impl Deref for BulkString {
71+
type Target = Vec<u8>;
72+
73+
fn deref(&self) -> &Self::Target {
74+
&self.0
75+
}
76+
}
77+
78+
impl AsRef<[u8]> for BulkString {
79+
fn as_ref(&self) -> &[u8] {
80+
&self.0
81+
}
82+
}
83+
84+
impl From<&str> for BulkString {
85+
fn from(s: &str) -> Self {
86+
BulkString(s.as_bytes().to_vec())
87+
}
88+
}
89+
90+
impl From<String> for BulkString {
91+
fn from(s: String) -> Self {
92+
BulkString(s.into_bytes())
93+
}
94+
}
95+
96+
impl From<&[u8]> for BulkString {
97+
fn from(s: &[u8]) -> Self {
98+
BulkString(s.to_vec())
99+
}
100+
}
101+
102+
impl<const N: usize> From<&[u8; N]> for BulkString {
103+
fn from(s: &[u8; N]) -> Self {
104+
BulkString(s.to_vec())
105+
}
106+
}
107+
108+
#[cfg(test)]
109+
mod tests {
110+
use crate::RespFrame;
111+
112+
use super::*;
113+
use anyhow::Result;
114+
115+
#[test]
116+
fn test_bulk_string_encode() {
117+
let frame: RespFrame = BulkString::new(b"hello".to_vec()).into();
118+
assert_eq!(frame.encode(), b"$5\r\nhello\r\n");
119+
}
120+
121+
#[test]
122+
fn test_null_bulk_string_encode() {
123+
let frame: RespFrame = RespNullBulkString.into();
124+
assert_eq!(frame.encode(), b"$-1\r\n");
125+
}
126+
127+
#[test]
128+
fn test_bulk_string_decode() -> Result<()> {
129+
let mut buf = BytesMut::new();
130+
buf.extend_from_slice(b"$5\r\nhello\r\n");
131+
132+
let frame = BulkString::decode(&mut buf)?;
133+
assert_eq!(frame, BulkString::new(b"hello"));
134+
135+
buf.extend_from_slice(b"$5\r\nhello");
136+
let ret = BulkString::decode(&mut buf);
137+
assert_eq!(ret.unwrap_err(), RespError::NotComplete);
138+
139+
buf.extend_from_slice(b"\r\n");
140+
let frame = BulkString::decode(&mut buf)?;
141+
assert_eq!(frame, BulkString::new(b"hello"));
142+
143+
Ok(())
144+
}
145+
146+
#[test]
147+
fn test_null_bulk_string_decode() -> Result<()> {
148+
let mut buf = BytesMut::new();
149+
buf.extend_from_slice(b"$-1\r\n");
150+
151+
let frame = RespNullBulkString::decode(&mut buf)?;
152+
assert_eq!(frame, RespNullBulkString);
153+
154+
Ok(())
155+
}
156+
}

0 commit comments

Comments
 (0)