8
8
9
9
mod errors;
10
10
mod hashes;
11
+ mod storage;
11
12
12
13
use std:: convert:: TryFrom ;
14
+ use std:: fmt:: Debug ;
15
+ use std:: hash;
13
16
14
17
use blake2b_simd:: { blake2b, Params as Blake2bVariable } ;
15
18
use blake2s_simd:: { blake2s, Params as Blake2sVariable } ;
16
- use bytes:: { BufMut , Bytes , BytesMut } ;
17
19
use sha2:: Digest ;
18
20
use tiny_keccak:: Keccak ;
19
21
use unsigned_varint:: { decode, encode} ;
20
22
21
23
pub use errors:: { DecodeError , DecodeOwnedError , EncodeError } ;
22
24
pub use hashes:: Hash ;
25
+ use std:: fmt;
26
+ use storage:: Storage ;
23
27
24
28
// Helper macro for encoding input into output using sha1, sha2, tiny_keccak, or blake2
25
29
macro_rules! encode {
@@ -104,15 +108,8 @@ pub fn encode(hash: Hash, input: &[u8]) -> Result<Multihash, EncodeError> {
104
108
let code = encode:: u16 ( hash. code ( ) , & mut buf) ;
105
109
let mut len_buf = encode:: u32_buffer ( ) ;
106
110
let size = encode:: u32 ( input. len ( ) as u32 , & mut len_buf) ;
107
-
108
- let total_len = code. len ( ) + size. len ( ) + input. len ( ) ;
109
-
110
- let mut output = BytesMut :: with_capacity ( total_len) ;
111
- output. put_slice ( code) ;
112
- output. put_slice ( size) ;
113
- output. put_slice ( input) ;
114
111
Ok ( Multihash {
115
- bytes : output . freeze ( ) ,
112
+ storage : Storage :: from_slices ( & [ & code , & size , & input ] ) ,
116
113
} )
117
114
} else {
118
115
let ( offset, mut output) = encode_hash ( hash) ;
@@ -135,31 +132,51 @@ pub fn encode(hash: Hash, input: &[u8]) -> Result<Multihash, EncodeError> {
135
132
} ) ;
136
133
137
134
Ok ( Multihash {
138
- bytes : output . freeze ( ) ,
135
+ storage : Storage :: from_slice ( & output ) ,
139
136
} )
140
137
}
141
138
}
142
139
143
- // Encode the given [`Hash`] value and ensure the returned [`BytesMut `]
140
+ // Encode the given [`Hash`] value and ensure the returned [`Vec<u8> `]
144
141
// has enough capacity to hold the actual digest.
145
- fn encode_hash ( hash : Hash ) -> ( usize , BytesMut ) {
142
+ fn encode_hash ( hash : Hash ) -> ( usize , Vec < u8 > ) {
146
143
let mut buf = encode:: u16_buffer ( ) ;
147
144
let code = encode:: u16 ( hash. code ( ) , & mut buf) ;
148
145
149
146
let len = code. len ( ) + 1 + usize:: from ( hash. size ( ) ) ;
150
147
151
- let mut output = BytesMut :: with_capacity ( len) ;
152
- output. put_slice ( code) ;
153
- output. put_u8 ( hash. size ( ) ) ;
148
+ let mut output = Vec :: with_capacity ( len) ;
149
+ output. extend_from_slice ( code) ;
150
+ output. push ( hash. size ( ) ) ;
154
151
output. resize ( len, 0 ) ;
155
152
156
153
( code. len ( ) + 1 , output)
157
154
}
158
155
159
156
/// Represents a valid multihash.
160
- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
157
+ #[ derive( Clone ) ]
161
158
pub struct Multihash {
162
- bytes : Bytes ,
159
+ storage : Storage ,
160
+ }
161
+
162
+ impl Debug for Multihash {
163
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
164
+ f. debug_tuple ( "Multihash" ) . field ( & self . as_bytes ( ) ) . finish ( )
165
+ }
166
+ }
167
+
168
+ impl PartialEq for Multihash {
169
+ fn eq ( & self , other : & Self ) -> bool {
170
+ self . storage . bytes ( ) == other. storage . bytes ( )
171
+ }
172
+ }
173
+
174
+ impl Eq for Multihash { }
175
+
176
+ impl hash:: Hash for Multihash {
177
+ fn hash < H : hash:: Hasher > ( & self , state : & mut H ) {
178
+ self . storage . bytes ( ) . hash ( state) ;
179
+ }
163
180
}
164
181
165
182
impl Multihash {
@@ -172,7 +189,7 @@ impl Multihash {
172
189
} ) ;
173
190
}
174
191
Ok ( Multihash {
175
- bytes : Bytes :: from ( bytes) ,
192
+ storage : Storage :: from_slice ( & bytes) ,
176
193
} )
177
194
}
178
195
@@ -183,17 +200,19 @@ impl Multihash {
183
200
184
201
/// Returns the bytes representation of the multihash.
185
202
pub fn to_vec ( & self ) -> Vec < u8 > {
186
- Vec :: from ( & self . bytes [ .. ] )
203
+ Vec :: from ( self . as_bytes ( ) )
187
204
}
188
205
189
206
/// Returns the bytes representation of this multihash.
190
207
pub fn as_bytes ( & self ) -> & [ u8 ] {
191
- & self . bytes
208
+ self . storage . bytes ( )
192
209
}
193
210
194
211
/// Builds a `MultihashRef` corresponding to this `Multihash`.
195
212
pub fn as_ref ( & self ) -> MultihashRef {
196
- MultihashRef { bytes : & self . bytes }
213
+ MultihashRef {
214
+ bytes : self . as_bytes ( ) ,
215
+ }
197
216
}
198
217
199
218
/// Returns which hashing algorithm is used in this multihash.
@@ -215,7 +234,7 @@ impl AsRef<[u8]> for Multihash {
215
234
216
235
impl < ' a > PartialEq < MultihashRef < ' a > > for Multihash {
217
236
fn eq ( & self , other : & MultihashRef < ' a > ) -> bool {
218
- & * self . bytes == other. bytes
237
+ & * self . as_bytes ( ) == other. as_bytes ( )
219
238
}
220
239
}
221
240
@@ -290,7 +309,7 @@ impl<'a> MultihashRef<'a> {
290
309
/// This operation allocates.
291
310
pub fn to_owned ( & self ) -> Multihash {
292
311
Multihash {
293
- bytes : Bytes :: copy_from_slice ( self . bytes ) ,
312
+ storage : Storage :: from_slice ( self . bytes ) ,
294
313
}
295
314
}
296
315
@@ -302,7 +321,7 @@ impl<'a> MultihashRef<'a> {
302
321
303
322
impl < ' a > PartialEq < Multihash > for MultihashRef < ' a > {
304
323
fn eq ( & self , other : & Multihash ) -> bool {
305
- self . bytes == & * other. bytes
324
+ self . as_bytes ( ) == & * other. as_bytes ( )
306
325
}
307
326
}
308
327
0 commit comments