11use std:: hash:: { DefaultHasher , Hash , Hasher } ;
2+ use std:: ops:: { Deref , DerefMut } ;
23use std:: panic:: Location ;
34
45use thiserror:: Error ;
6+ use zerocopy:: FromBytes ;
57
68/// `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+ }
913
1014pub const INFO_HASH_BYTES_LEN : usize = 20 ;
1115
@@ -17,10 +21,9 @@ impl InfoHash {
1721 /// Will panic if byte slice does not contains the exact amount of bytes need for the `InfoHash`.
1822 #[ must_use]
1923 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 }
2427 }
2528
2629 /// Returns the `InfoHash` internal byte array.
@@ -36,6 +39,34 @@ impl InfoHash {
3639 }
3740}
3841
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+
3970impl Ord for InfoHash {
4071 fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
4172 self . 0 . cmp ( & other. 0 )
@@ -60,7 +91,7 @@ impl std::str::FromStr for InfoHash {
6091 type Err = binascii:: ConvertError ;
6192
6293 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
63- let mut i = Self ( [ 0u8 ; 20 ] ) ;
94+ let mut i = Self :: default ( ) ;
6495 if s. len ( ) != 40 {
6596 return Err ( binascii:: ConvertError :: InvalidInputLength ) ;
6697 }
@@ -72,7 +103,7 @@ impl std::str::FromStr for InfoHash {
72103impl std:: convert:: From < & [ u8 ] > for InfoHash {
73104 fn from ( data : & [ u8 ] ) -> InfoHash {
74105 assert_eq ! ( data. len( ) , 20 ) ;
75- let mut ret = InfoHash ( [ 0u8 ; 20 ] ) ;
106+ let mut ret = Self :: default ( ) ;
76107 ret. 0 . clone_from_slice ( data) ;
77108 ret
78109 }
@@ -82,23 +113,28 @@ impl std::convert::From<&[u8]> for InfoHash {
82113impl std:: convert:: From < & DefaultHasher > for InfoHash {
83114 fn from ( data : & DefaultHasher ) -> InfoHash {
84115 let n = data. finish ( ) . to_le_bytes ( ) ;
85- InfoHash ( [
116+ let bytes = [
86117 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 ] ,
87118 n[ 3 ] ,
88- ] )
119+ ] ;
120+ let data = aquatic_udp_protocol:: InfoHash ( bytes) ;
121+ Self { data }
89122 }
90123}
91124
92125impl std:: convert:: From < & i32 > for InfoHash {
93126 fn from ( n : & i32 ) -> InfoHash {
94127 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 }
96131 }
97132}
98133
99134impl 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 }
102138 }
103139}
104140
@@ -171,7 +207,7 @@ impl<'v> serde::de::Visitor<'v> for InfoHashVisitor {
171207 ) ) ;
172208 }
173209
174- let mut res = InfoHash ( [ 0u8 ; 20 ] ) ;
210+ let mut res = InfoHash :: default ( ) ;
175211
176212 if binascii:: hex2bin ( v. as_bytes ( ) , & mut res. 0 ) . is_err ( ) {
177213 return Err ( serde:: de:: Error :: invalid_value (
0 commit comments