1+ use crate :: error:: AppError ;
12use crate :: serde:: encode:: { Encode , Encoded } ;
3+ use crate :: serde:: decode:: Decode ;
4+ use crate :: verify:: verify_bytes_read_eq;
5+
6+
7+ const DEFAULT_CONSTR : u8 = 0x80 ;
8+ const SMALL_ULONG_CONSTR : u8 = 0x53 ;
9+ const ULONG_0_CONSTR : u8 = 0x44 ;
210
311impl Encode for u64 {
412 fn encode ( & self ) -> Encoded {
513 match self {
6- 0 => Encoded :: new_empty ( 0x44 ) ,
7- x if x > & & 0 && x <= & 255 => Encoded :: new_fixed ( 0x53 , x. to_be_bytes ( ) . to_vec ( ) ) ,
8- _ => Encoded :: new_fixed ( 0x80 , self . to_be_bytes ( ) . to_vec ( ) ) ,
14+ 0 => Encoded :: new_empty ( ULONG_0_CONSTR ) ,
15+ x if x > & & 0 && x <= & 255 => Encoded :: new_fixed ( SMALL_ULONG_CONSTR , x. to_be_bytes ( ) . to_vec ( ) ) ,
16+ _ => Encoded :: new_fixed ( DEFAULT_CONSTR , self . to_be_bytes ( ) . to_vec ( ) ) ,
17+ }
18+ }
19+ }
20+
21+ impl Decode for u64 {
22+
23+ fn can_decode ( iter : impl Iterator < Item = u8 > ) -> bool {
24+ match iter. peekable ( ) . peek ( ) {
25+ Some ( & DEFAULT_CONSTR ) => true ,
26+ Some ( & SMALL_ULONG_CONSTR ) => true ,
27+ Some ( & ULONG_0_CONSTR ) => true ,
28+ _ => false
29+ }
30+ }
31+
32+ fn try_decode ( mut iter : impl Iterator < Item = u8 > ) -> Result < Self , crate :: error:: AppError >
33+ where
34+ Self : Sized {
35+ match iter. next ( ) {
36+ Some ( DEFAULT_CONSTR ) => Ok ( parse_ulong ( iter) ?) ,
37+ Some ( SMALL_ULONG_CONSTR ) => Ok ( parse_small_ulong ( iter) ?) ,
38+ Some ( ULONG_0_CONSTR ) => Ok ( 0 ) ,
39+ Some ( c) => Err ( AppError :: DeserializationIllegalConstructorError ( c) ) ,
40+ None => Err ( AppError :: IteratorEmptyOrTooShortError ) ,
941 }
1042 }
1143}
1244
45+ fn parse_ulong ( mut iter : impl Iterator < Item = u8 > ) -> Result < u64 , AppError > {
46+ let mut byte_vals = [ 0 ; 8 ] ;
47+ let mut index = 0 ;
48+ for b in iter. take ( 8 ) {
49+ byte_vals[ index] = b;
50+ index += 1 ;
51+ }
52+ verify_bytes_read_eq ( index, 8 ) ?;
53+ Ok ( u64:: from_be_bytes ( byte_vals) )
54+ }
55+
56+ fn parse_small_ulong ( mut iter : impl Iterator < Item = u8 > ) -> Result < u64 , AppError > {
57+ if let Some ( val) = iter. next ( ) {
58+ Ok ( val as u64 )
59+ } else {
60+ Err ( AppError :: IteratorEmptyOrTooShortError )
61+ }
62+ }
63+
1364#[ cfg( test) ]
1465mod test {
1566
@@ -32,4 +83,56 @@ mod test {
3283 let val: u64 = 0 ;
3384 assert_eq ! ( val. encode( ) . constructor( ) , 0x44 ) ;
3485 }
86+
87+ #[ test]
88+ fn can_deocde_returns_true_if_constructor_is_valid ( ) {
89+ let val_norm = vec ! [ 0x80 ] ;
90+ let val_small = vec ! [ 0x53 ] ;
91+ let val_zero = vec ! [ 0x44 ] ;
92+ assert_eq ! ( u64 :: can_decode( val_norm. into_iter( ) ) , true ) ;
93+ assert_eq ! ( u64 :: can_decode( val_small. into_iter( ) ) , true ) ;
94+ assert_eq ! ( u64 :: can_decode( val_zero. into_iter( ) ) , true ) ;
95+ }
96+
97+ #[ test]
98+ fn can_decode_return_false_if_constructor_is_invalid ( ) {
99+ let val = vec ! [ 0x71 ] ;
100+ assert_eq ! ( u64 :: can_decode( val. into_iter( ) ) , false ) ;
101+ }
102+
103+ #[ test]
104+ fn try_decode_returns_correct_value ( ) {
105+ let val = vec ! [ 0x80 , 0x01 , 0x01 , 0x11 , 0x10 , 0x10 , 0x00 , 0x00 , 0x10 ] ;
106+ assert_eq ! ( u64 :: try_decode( val. into_iter( ) ) . unwrap( ) , 72357829700222992 ) ;
107+ }
108+
109+ #[ test]
110+ fn decode_returns_error_when_value_bytes_are_invalid ( ) {
111+ let val = vec ! [ 0x66 , 0x44 ] ;
112+ assert ! ( u64 :: try_decode( val. into_iter( ) ) . is_err( ) ) ;
113+ }
114+
115+ #[ test]
116+ fn decode_returns_error_when_bytes_are_missing ( ) {
117+ let val = vec ! [ 0x70 , 0x00 , 0x00 , 0x01 ] ;
118+ assert ! ( u64 :: try_decode( val. into_iter( ) ) . is_err( ) ) ;
119+ }
120+
121+ #[ test]
122+ fn try_decode_can_decode_zero_length_value_zero ( ) {
123+ let val = vec ! [ 0x44 ] ;
124+ assert_eq ! ( u64 :: try_decode( val. into_iter( ) ) . unwrap( ) , 0 ) ;
125+ }
126+
127+ #[ test]
128+ fn try_decode_can_decode_smallulong_values ( ) {
129+ let val = vec ! [ 0x53 , 0xff ] ;
130+ assert_eq ! ( u64 :: try_decode( val. into_iter( ) ) . unwrap( ) , 255 ) ;
131+ }
132+
133+ #[ test]
134+ fn try_decode_returns_error_when_parsing_small_ulong_and_bytes_are_missing ( ) {
135+ let val = vec ! [ 0x53 ] ;
136+ assert ! ( u64 :: try_decode( val. into_iter( ) ) . is_err( ) ) ;
137+ }
35138}
0 commit comments