1
+ use crate :: error:: AppError ;
1
2
use 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 ;
2
10
3
11
impl Encode for u64 {
4
12
fn encode ( & self ) -> Encoded {
5
13
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 ) ,
9
41
}
10
42
}
11
43
}
12
44
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
+
13
64
#[ cfg( test) ]
14
65
mod test {
15
66
@@ -32,4 +83,56 @@ mod test {
32
83
let val: u64 = 0 ;
33
84
assert_eq ! ( val. encode( ) . constructor( ) , 0x44 ) ;
34
85
}
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
+ }
35
138
}
0 commit comments