1- use std:: collections:: BTreeMap ;
2-
3- use bytes:: BytesMut ;
1+ use bytes:: { Buf , BytesMut } ;
42use enum_dispatch:: enum_dispatch;
3+ use std:: collections:: BTreeMap ;
4+ use thiserror:: Error ;
55
6+ mod decode;
67mod encode;
78
9+ const CRLF : & [ u8 ] = b"\r \n " ;
10+ const CRLF_LEN : usize = CRLF . len ( ) ;
11+
812#[ enum_dispatch]
913pub trait RespEncode {
1014 fn encode ( self ) -> Vec < u8 > ;
1115}
1216
13- pub trait RespDecode {
14- fn decode ( buf : Self ) -> Result < RespFrame , String > ;
17+ // Sized 表示这个 trait 只能被 [大小确定的类型] 实现
18+ // 因为 decode 方法的返回值是一个 Self, 因此必须将这个 trait 标记为 Sized
19+ pub trait RespDecode : Sized {
20+ const PREFIX : & ' static str ;
21+ fn decode ( buf : & mut BytesMut ) -> Result < Self , RespError > ;
22+ fn expect_length ( buf : & [ u8 ] ) -> Result < usize , RespError > ;
23+ }
24+
25+ #[ derive( Error , Debug , PartialEq , Eq ) ]
26+ pub enum RespError {
27+ // region: --- thiserror format usage
28+
29+ // #[error("{var}")] ⟶ write!("{}", self.var)
30+ // #[error("{0}")] ⟶ write!("{}", self.0)
31+ // #[error("{var:?}")] ⟶ write!("{:?}", self.var)
32+ // #[error("{0:?}")] ⟶ write!("{:?}", self.0)
33+
34+ // endregion: --- thiserror format usage
35+ #[ error( "Invalid frame: {0}" ) ] // 这里的 0 表示 self.0。 会转化为 write!
36+ InvalidFrame ( String ) ,
37+ #[ error( "Invalid frame type: {0}" ) ]
38+ InvalidFrameType ( String ) ,
39+ #[ error( "Invalid frame length: {0}" ) ]
40+ InvalidFrameLength ( isize ) ,
41+ #[ error( "Frame is not complete" ) ]
42+ NotComplete ,
43+
44+ #[ error( "Parse error: {0}" ) ]
45+ ParseIntError ( #[ from] std:: num:: ParseIntError ) ,
46+ #[ error( "Utf8 error: {0}" ) ]
47+ Utf8Error ( #[ from] std:: string:: FromUtf8Error ) ,
48+ #[ error( "Parse float error: {0}" ) ]
49+ ParseFloatError ( #[ from] std:: num:: ParseFloatError ) ,
1550}
51+
52+ // pub trait RespDecode: Sized {
53+ // const PREFIX: &'static str;
54+ // fn decode(buf: &mut BytesMut) -> Result<Self, RespError>;
55+ // fn expect_length(buf: &[u8]) -> Result<usize, RespError>;
56+ // }
57+
1658// 之所以要定义一些新的结构体, 是因为要在实现 trait 的时候, 要区分开这些类型
1759#[ enum_dispatch( RespEncode ) ]
1860pub enum RespFrame {
@@ -35,12 +77,19 @@ pub enum RespFrame {
3577// 2. 新类型模式:这是 Rust 中常用的一种模式,用于在类型系统层面区分不同用途的相同底层类型。比如,你可能想区分普通的字符串和特定格式的字符串。
3678// 3. 添加方法:你可以为 SimpleString 实现方法,这些方法特定于这种类型的字符串。
3779// 4. 语义清晰:在复杂的数据结构中(如你展示的 RespFrame 枚举),使用 SimpleString 而不是直接使用 String 可以使代码的意图更加明确。
80+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
3881pub struct SimpleString ( String ) ; // Simple String, 用于存储简单字符串
82+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
3983pub struct SimpleError ( String ) ;
84+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
4085pub struct BulkString ( Vec < u8 > ) ; // 单个二进制字符串, 用于存储二进制数据(最大512MB)
86+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
4187pub struct RespNullBulkString ;
88+
4289pub struct RespArray ( Vec < RespFrame > ) ;
90+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
4391pub struct RespNullArray ;
92+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd ) ]
4493pub struct RespNull ;
4594#[ derive( Default ) ]
4695pub struct RespMap ( BTreeMap < String , RespFrame > ) ; // 改为 BTreeMap, 用于有序的 key-value 数据
@@ -84,14 +133,91 @@ impl RespSet {
84133 }
85134}
86135
87- impl RespDecode for BytesMut {
88- fn decode ( _buf : Self ) -> Result < RespFrame , String > {
89- todo ! ( )
136+ // utility functions
137+ fn extract_fixed_data (
138+ buf : & mut BytesMut ,
139+ expect : & str ,
140+ expect_type : & str ,
141+ ) -> Result < ( ) , RespError > {
142+ if buf. len ( ) < expect. len ( ) {
143+ return Err ( RespError :: NotComplete ) ;
90144 }
145+
146+ if !buf. starts_with ( expect. as_bytes ( ) ) {
147+ return Err ( RespError :: InvalidFrameType ( format ! (
148+ "expect: {}, got: {:?}" ,
149+ expect_type, buf
150+ ) ) ) ;
151+ }
152+
153+ buf. advance ( expect. len ( ) ) ;
154+ Ok ( ( ) )
91155}
92156
93- // impl RespEncode for RespFrame {
94- // fn encode(self) -> Vec<u8> {
95- // todo!()
96- // }
97- // }
157+ fn extract_simple_frame_data ( buf : & [ u8 ] , prefix : & str ) -> Result < usize , RespError > {
158+ if buf. len ( ) < 3 {
159+ return Err ( RespError :: NotComplete ) ;
160+ }
161+
162+ if !buf. starts_with ( prefix. as_bytes ( ) ) {
163+ return Err ( RespError :: InvalidFrameType ( format ! (
164+ "expect: SimpleString({}), got: {:?}" ,
165+ prefix, buf
166+ ) ) ) ;
167+ }
168+
169+ let end = find_crlf ( buf, 1 ) . ok_or ( RespError :: NotComplete ) ?;
170+
171+ Ok ( end)
172+ }
173+
174+ // find nth CRLF in the buffer
175+ fn find_crlf ( buf : & [ u8 ] , nth : usize ) -> Option < usize > {
176+ let mut count = 0 ;
177+ for i in 1 ..buf. len ( ) - 1 {
178+ if buf[ i] == b'\r' && buf[ i + 1 ] == b'\n' {
179+ count += 1 ;
180+ if count == nth {
181+ return Some ( i) ;
182+ }
183+ }
184+ }
185+ None
186+ }
187+
188+ fn parse_length ( buf : & [ u8 ] , prefix : & str ) -> Result < ( usize , usize ) , RespError > {
189+ let end = extract_simple_frame_data ( buf, prefix) ?;
190+ let s = String :: from_utf8_lossy ( & buf[ prefix. len ( ) ..end] ) ;
191+ Ok ( ( end, s. parse ( ) ?) )
192+ }
193+
194+ fn calc_total_length ( buf : & [ u8 ] , end : usize , len : usize , prefix : & str ) -> Result < usize , RespError > {
195+ let mut total = end + CRLF_LEN ;
196+ let mut data = & buf[ total..] ;
197+ match prefix {
198+ "*" | "~" => {
199+ // find nth CRLF in the buffer, for array and set, we need to find 1 CRLF for each element
200+ for _ in 0 ..len {
201+ let len = RespFrame :: expect_length ( data) ?;
202+ data = & data[ len..] ;
203+ total += len;
204+ }
205+ Ok ( total)
206+ }
207+ "%" => {
208+ // find nth CRLF in the buffer. For map, we need to find 2 CRLF for each key-value pair
209+ for _ in 0 ..len {
210+ let len = SimpleString :: expect_length ( data) ?;
211+
212+ data = & data[ len..] ;
213+ total += len;
214+
215+ let len = RespFrame :: expect_length ( data) ?;
216+ data = & data[ len..] ;
217+ total += len;
218+ }
219+ Ok ( total)
220+ }
221+ _ => Ok ( len + CRLF_LEN ) ,
222+ }
223+ }
0 commit comments