1
1
use std:: hash:: { DefaultHasher , Hash , Hasher } ;
2
+ use std:: ops:: { Deref , DerefMut } ;
2
3
use std:: panic:: Location ;
3
4
4
5
use thiserror:: Error ;
6
+ use zerocopy:: FromBytes ;
5
7
6
8
/// `BitTorrent` Info Hash v1
7
- #[ derive( PartialEq , Eq , Hash , Clone , Copy , Default , Debug ) ]
8
- pub struct InfoHash ( pub [ u8 ; 20 ] ) ;
9
+ #[ derive( PartialEq , Eq , Hash , Clone , Copy , Debug ) ]
10
+ pub struct InfoHash {
11
+ data : aquatic_udp_protocol:: InfoHash ,
12
+ }
9
13
10
14
pub const INFO_HASH_BYTES_LEN : usize = 20 ;
11
15
@@ -17,10 +21,9 @@ impl InfoHash {
17
21
/// Will panic if byte slice does not contains the exact amount of bytes need for the `InfoHash`.
18
22
#[ must_use]
19
23
pub fn from_bytes ( bytes : & [ u8 ] ) -> Self {
20
- assert_eq ! ( bytes. len( ) , INFO_HASH_BYTES_LEN ) ;
21
- let mut ret = Self ( [ 0u8 ; INFO_HASH_BYTES_LEN ] ) ;
22
- ret. 0 . clone_from_slice ( bytes) ;
23
- ret
24
+ let data = aquatic_udp_protocol:: InfoHash :: read_from ( bytes) . expect ( "it should have the exact amount of bytes" ) ;
25
+
26
+ Self { data }
24
27
}
25
28
26
29
/// Returns the `InfoHash` internal byte array.
@@ -36,13 +39,41 @@ impl InfoHash {
36
39
}
37
40
}
38
41
42
+ impl Default for InfoHash {
43
+ fn default ( ) -> Self {
44
+ Self {
45
+ data : aquatic_udp_protocol:: InfoHash ( Default :: default ( ) ) ,
46
+ }
47
+ }
48
+ }
49
+
50
+ impl From < aquatic_udp_protocol:: InfoHash > for InfoHash {
51
+ fn from ( data : aquatic_udp_protocol:: InfoHash ) -> Self {
52
+ Self { data }
53
+ }
54
+ }
55
+
56
+ impl Deref for InfoHash {
57
+ type Target = aquatic_udp_protocol:: InfoHash ;
58
+
59
+ fn deref ( & self ) -> & Self :: Target {
60
+ & self . data
61
+ }
62
+ }
63
+
64
+ impl DerefMut for InfoHash {
65
+ fn deref_mut ( & mut self ) -> & mut Self :: Target {
66
+ & mut self . data
67
+ }
68
+ }
69
+
39
70
impl Ord for InfoHash {
40
71
fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
41
72
self . 0 . cmp ( & other. 0 )
42
73
}
43
74
}
44
75
45
- impl std :: cmp :: PartialOrd < InfoHash > for InfoHash {
76
+ impl PartialOrd < InfoHash > for InfoHash {
46
77
fn partial_cmp ( & self , other : & InfoHash ) -> Option < std:: cmp:: Ordering > {
47
78
Some ( self . cmp ( other) )
48
79
}
@@ -60,7 +91,7 @@ impl std::str::FromStr for InfoHash {
60
91
type Err = binascii:: ConvertError ;
61
92
62
93
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
63
- let mut i = Self ( [ 0u8 ; 20 ] ) ;
94
+ let mut i = Self :: default ( ) ;
64
95
if s. len ( ) != 40 {
65
96
return Err ( binascii:: ConvertError :: InvalidInputLength ) ;
66
97
}
@@ -72,7 +103,7 @@ impl std::str::FromStr for InfoHash {
72
103
impl std:: convert:: From < & [ u8 ] > for InfoHash {
73
104
fn from ( data : & [ u8 ] ) -> InfoHash {
74
105
assert_eq ! ( data. len( ) , 20 ) ;
75
- let mut ret = InfoHash ( [ 0u8 ; 20 ] ) ;
106
+ let mut ret = Self :: default ( ) ;
76
107
ret. 0 . clone_from_slice ( data) ;
77
108
ret
78
109
}
@@ -82,23 +113,28 @@ impl std::convert::From<&[u8]> for InfoHash {
82
113
impl std:: convert:: From < & DefaultHasher > for InfoHash {
83
114
fn from ( data : & DefaultHasher ) -> InfoHash {
84
115
let n = data. finish ( ) . to_le_bytes ( ) ;
85
- InfoHash ( [
116
+ let bytes = [
86
117
n[ 0 ] , n[ 1 ] , n[ 2 ] , n[ 3 ] , n[ 4 ] , n[ 5 ] , n[ 6 ] , n[ 7 ] , n[ 0 ] , n[ 1 ] , n[ 2 ] , n[ 3 ] , n[ 4 ] , n[ 5 ] , n[ 6 ] , n[ 7 ] , n[ 0 ] , n[ 1 ] , n[ 2 ] ,
87
118
n[ 3 ] ,
88
- ] )
119
+ ] ;
120
+ let data = aquatic_udp_protocol:: InfoHash ( bytes) ;
121
+ Self { data }
89
122
}
90
123
}
91
124
92
125
impl std:: convert:: From < & i32 > for InfoHash {
93
126
fn from ( n : & i32 ) -> InfoHash {
94
127
let n = n. to_le_bytes ( ) ;
95
- InfoHash ( [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , n[ 0 ] , n[ 1 ] , n[ 2 ] , n[ 3 ] ] )
128
+ let bytes = [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , n[ 0 ] , n[ 1 ] , n[ 2 ] , n[ 3 ] ] ;
129
+ let data = aquatic_udp_protocol:: InfoHash ( bytes) ;
130
+ Self { data }
96
131
}
97
132
}
98
133
99
134
impl std:: convert:: From < [ u8 ; 20 ] > for InfoHash {
100
- fn from ( val : [ u8 ; 20 ] ) -> Self {
101
- InfoHash ( val)
135
+ fn from ( bytes : [ u8 ; 20 ] ) -> Self {
136
+ let data = aquatic_udp_protocol:: InfoHash ( bytes) ;
137
+ Self { data }
102
138
}
103
139
}
104
140
@@ -171,7 +207,7 @@ impl<'v> serde::de::Visitor<'v> for InfoHashVisitor {
171
207
) ) ;
172
208
}
173
209
174
- let mut res = InfoHash ( [ 0u8 ; 20 ] ) ;
210
+ let mut res = InfoHash :: default ( ) ;
175
211
176
212
if binascii:: hex2bin ( v. as_bytes ( ) , & mut res. 0 ) . is_err ( ) {
177
213
return Err ( serde:: de:: Error :: invalid_value (
0 commit comments