Skip to content
This repository was archived by the owner on Nov 30, 2022. It is now read-only.

Commit 433b4d7

Browse files
committed
Introduce HexWriter
this structs create an hex string from a writer, in cases where you have an encodable object it allows skipping the creation of the intermediate Vec<u8>
1 parent a7e3ff6 commit 433b4d7

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

src/hex.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,45 @@ impl ToHex for [u8] {
219219
}
220220
}
221221

222+
/// A struct implementing [`io::Write`] that converts what's written into it
223+
/// in an hex String
224+
///
225+
/// If you already have the data to be converted in a `Vec<u8>` use [`ToHex`]
226+
/// but if you have an encodable object, by using this you avoid the
227+
/// serialization to `Vec<u8>` by going directly to `String`.
228+
///
229+
/// Note that to achieve better perfomance than [`ToHex`] the struct must be
230+
/// created with the right `capacity` of the end hex string result so that the
231+
/// inner `String` doesn't re-allocate
232+
pub struct HexWriter(String);
233+
234+
impl HexWriter {
235+
/// Creates a new [`HexWriter`] specify the `capacity` of the inner `String` that will contain
236+
/// the hex value
237+
pub fn new(capacity: usize) -> Self {
238+
HexWriter(String::with_capacity(capacity))
239+
}
240+
241+
/// Get the hex string result
242+
pub fn result(self) -> String {
243+
self.0
244+
}
245+
}
246+
247+
impl io::Write for HexWriter {
248+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
249+
use core::fmt::Write;
250+
for ch in buf {
251+
write!(self.0, "{:02x}", ch).expect("writing to string");
252+
}
253+
Ok(buf.len())
254+
}
255+
256+
fn flush(&mut self) -> io::Result<()> {
257+
Ok(())
258+
}
259+
}
260+
222261
#[cfg(any(test, feature = "std", feature = "alloc"))]
223262
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
224263
impl FromHex for Vec<u8> {
@@ -276,6 +315,7 @@ mod tests {
276315
use super::*;
277316

278317
use core::fmt;
318+
use std::io::Write;
279319

280320
#[test]
281321
#[cfg(any(feature = "std", feature = "alloc"))]
@@ -398,5 +438,41 @@ mod tests {
398438
Err(Error::InvalidChar(194))
399439
);
400440
}
441+
442+
443+
#[test]
444+
fn hex_writer() {
445+
let vec: Vec<_> = (0u8..32).collect();
446+
let mut writer = HexWriter::new(64);
447+
writer.write_all(&vec[..]).unwrap();
448+
assert_eq!(vec.to_hex(), writer.result());
449+
}
401450
}
402451

452+
453+
#[cfg(all(test, feature="unstable"))]
454+
mod benches {
455+
use test::{Bencher, black_box};
456+
use super::{ToHex, HexWriter};
457+
use std::io::Write;
458+
use crate::{sha256, Hash};
459+
460+
#[bench]
461+
fn bench_to_hex(bh: &mut Bencher) {
462+
let hash = sha256::Hash::hash(&[0; 1]);
463+
bh.iter(|| {
464+
black_box(hash.to_hex());
465+
})
466+
}
467+
468+
469+
#[bench]
470+
fn bench_to_hex_writer(bh: &mut Bencher) {
471+
let hash = sha256::Hash::hash(&[0; 1]);
472+
bh.iter(|| {
473+
let mut writer = HexWriter::new(64);
474+
writer.write_all(hash.as_inner()).unwrap();
475+
black_box(writer.result());
476+
})
477+
}
478+
}

0 commit comments

Comments
 (0)