11use std:: {
2- collections:: { HashMap , HashSet } ,
3- ops:: Deref ,
2+ collections:: BTreeMap ,
3+ ops:: { Deref , DerefMut } ,
44} ;
55
66use crate :: {
@@ -27,7 +27,7 @@ impl RespEncode for SimpleError {
2727// - integer: ":[<+|->]<value>\r\n"
2828impl RespEncode for i64 {
2929 fn encode ( self ) -> Vec < u8 > {
30- let sign = if self < 0 { "- " } else { "+" } ;
30+ let sign = if self < 0 { "" } else { "+" } ; // -1 => -1, 1 => +1
3131 format ! ( ":{}{}\r \n " , sign, self ) . into_bytes ( )
3232 }
3333}
@@ -91,9 +91,16 @@ impl RespEncode for bool {
9191// - double: ",[<+|->]<integral>[.<fractional>][<E|e>[sign]<exponent>]\r\n"
9292impl RespEncode for f64 {
9393 fn encode ( self ) -> Vec < u8 > {
94- // scientific natation
95- // format: {:+e}
96- format ! ( ",{:+e}\r \n " , self ) . into_bytes ( )
94+ let mut buf = Vec :: with_capacity ( 32 ) ;
95+ let ret = if self . abs ( ) > 1e+8 || self . abs ( ) < 1e-8 {
96+ format ! ( ",{:+e}\r \n " , self )
97+ } else {
98+ let sign = if self < 0.0 { "" } else { "+" } ;
99+ format ! ( ",{}{}\r \n " , sign, self )
100+ } ;
101+
102+ buf. extend_from_slice ( & ret. into_bytes ( ) ) ;
103+ buf
97104 }
98105}
99106
@@ -169,17 +176,141 @@ impl Deref for RespArray {
169176}
170177
171178impl Deref for RespMap {
172- type Target = HashMap < String , RespFrame > ;
179+ type Target = BTreeMap < String , RespFrame > ;
173180
174181 fn deref ( & self ) -> & Self :: Target {
175182 & self . 0
176183 }
177184}
178185
186+ impl DerefMut for RespMap {
187+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
188+ & mut self . 0
189+ }
190+ }
191+
179192impl Deref for RespSet {
180- type Target = HashSet < RespFrame > ;
193+ type Target = Vec < RespFrame > ;
181194
182195 fn deref ( & self ) -> & Self :: Target {
183196 & self . 0
184197 }
185198}
199+
200+ #[ cfg( test) ]
201+ mod test {
202+ use super :: * ;
203+
204+ #[ test]
205+ fn test_simple_string_encode ( ) {
206+ let frame: RespFrame = SimpleString :: new ( "OK" . to_string ( ) ) . into ( ) ;
207+ assert_eq ! ( frame. encode( ) , b"+OK\r \n " ) ;
208+ }
209+
210+ #[ test]
211+ fn test_error_encode ( ) {
212+ let frame: RespFrame = SimpleError :: new ( "Error message" . to_string ( ) ) . into ( ) ;
213+ assert_eq ! ( frame. encode( ) , b"-Error message\r \n " ) ;
214+ }
215+
216+ #[ test]
217+ fn test_integer_encode ( ) {
218+ let frame: RespFrame = 123 . into ( ) ;
219+ assert_eq ! ( frame. encode( ) , b":+123\r \n " ) ;
220+
221+ // println!("{:?}", String::from_utf8_lossy(&frame.encode()));
222+
223+ let frame: RespFrame = ( -123 ) . into ( ) ;
224+ assert_eq ! ( frame. encode( ) , b":-123\r \n " ) ;
225+ }
226+
227+ #[ test]
228+ fn test_bulk_string_encode ( ) {
229+ let frame: RespFrame = BulkString :: new ( b"hello" . to_vec ( ) ) . into ( ) ;
230+ assert_eq ! ( frame. encode( ) , b"$5\r \n hello\r \n " ) ;
231+ }
232+
233+ #[ test]
234+ fn test_null_bulk_string_encode ( ) {
235+ let frame: RespFrame = RespNullBulkString . into ( ) ;
236+ assert_eq ! ( frame. encode( ) , b"$-1\r \n " ) ;
237+ }
238+
239+ #[ test]
240+ fn test_array_encode ( ) {
241+ let frame: RespFrame = RespArray :: new ( vec ! [
242+ SimpleString :: new( "OK" . to_string( ) ) . into( ) ,
243+ 123 . into( ) ,
244+ BulkString :: new( b"hello" . to_vec( ) ) . into( ) ,
245+ ] )
246+ . into ( ) ;
247+ assert_eq ! ( frame. encode( ) , b"*3\r \n +OK\r \n :+123\r \n $5\r \n hello\r \n " ) ;
248+ }
249+
250+ #[ test]
251+ fn test_null_array_encode ( ) {
252+ let frame: RespFrame = RespNullArray . into ( ) ;
253+ assert_eq ! ( frame. encode( ) , b"*-1\r \n " ) ;
254+ }
255+
256+ #[ test]
257+ fn test_null_encode ( ) {
258+ let frame: RespFrame = RespNull . into ( ) ;
259+ assert_eq ! ( frame. encode( ) , b"_\r \n " ) ;
260+ }
261+
262+ #[ test]
263+ fn test_boolean_encode ( ) {
264+ // into 和 from 是互斥的
265+ // let frame: RespFrame = true.into();
266+ let frame = RespFrame :: from ( true ) ;
267+ assert_eq ! ( frame. encode( ) , b"#t\r \n " ) ;
268+
269+ let frame: RespFrame = false . into ( ) ;
270+ assert_eq ! ( frame. encode( ) , b"#f\r \n " ) ;
271+ }
272+
273+ #[ test]
274+ fn test_double_encode ( ) {
275+ let frame: RespFrame = ( 123.456 ) . into ( ) ;
276+ assert_eq ! ( frame. encode( ) , b",+123.456\r \n " ) ;
277+
278+ let frame: RespFrame = ( -123.456 ) . into ( ) ;
279+ assert_eq ! ( frame. encode( ) , b",-123.456\r \n " ) ;
280+
281+ let frame: RespFrame = 1.23456e+8 . into ( ) ;
282+ assert_eq ! ( frame. encode( ) , b",+1.23456e8\r \n " ) ;
283+
284+ let frame: RespFrame = ( -1.23456e-9 ) . into ( ) ;
285+ assert_eq ! ( & frame. encode( ) , b",-1.23456e-9\r \n " ) ;
286+ }
287+
288+ #[ test]
289+ fn test_map_encode ( ) {
290+ let mut map = RespMap :: new ( ) ;
291+ map. insert (
292+ "hello" . to_string ( ) ,
293+ BulkString :: new ( "world" . to_string ( ) ) . into ( ) ,
294+ ) ;
295+ map. insert ( "foo" . to_string ( ) , ( -123456.789 ) . into ( ) ) ;
296+
297+ let frame: RespFrame = map. into ( ) ;
298+ assert_eq ! (
299+ & frame. encode( ) ,
300+ b"%2\r \n +foo\r \n ,-123456.789\r \n +hello\r \n $5\r \n world\r \n "
301+ ) ;
302+ }
303+
304+ #[ test]
305+ fn test_set_encode ( ) {
306+ let frame: RespFrame = RespSet :: new ( [
307+ RespArray :: new ( [ 1234 . into ( ) , true . into ( ) ] ) . into ( ) ,
308+ BulkString :: new ( "world" . to_string ( ) ) . into ( ) ,
309+ ] )
310+ . into ( ) ;
311+ assert_eq ! (
312+ frame. encode( ) ,
313+ b"~2\r \n *2\r \n :+1234\r \n #t\r \n $5\r \n world\r \n "
314+ ) ;
315+ }
316+ }
0 commit comments