Skip to content

Commit

Permalink
Add ToHexIterator.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomusdrw committed Jan 10, 2020
1 parent 3e773fe commit 3df0b2e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 52 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustc-hex"
version = "2.0.1"
version = "2.1.0"
authors = ["The Rust Project Developers", "debris <[email protected]>", "Robert Habermeier"]
license = "MIT/Apache-2.0"
repository = "https://github.com/debris/rustc-hex"
Expand All @@ -9,6 +9,7 @@ keywords = ["rustc", "serialize", "hex"]
description = """
rustc-serialize compatible hex conversion traits
"""
edition = "2018"

[features]
default = ["std"]
Expand Down
99 changes: 48 additions & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,26 @@

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(feature = "std")]
extern crate core;

#[cfg(feature = "std")]
use std::fmt;

#[cfg(not(feature = "std"))]
use core::fmt;

use core::iter::{self, FromIterator};

pub use self::FromHexError::*;

/// A trait for converting a value to hexadecimal encoding
pub trait ToHex {
/// Converts the value of `self` to a hex value, constructed from
/// an iterator of characaters.
/// an iterator of characters.
fn to_hex<T: FromIterator<char>>(&self) -> T;
}

static CHARS: &'static [u8] = b"0123456789abcdef";

impl ToHex for [u8] {
/// Turn a vector of `u8` bytes into a hexadecimal string.
/// Turn a slice of `u8` bytes into a hexadecimal string.
///
/// # Example
///
/// ```rust
/// extern crate rustc_hex;
/// use rustc_hex::ToHex;
///
/// fn main () {
Expand All @@ -48,56 +40,61 @@ impl ToHex for [u8] {
/// }
/// ```
fn to_hex<T: FromIterator<char>>(&self) -> T {
struct SliceToHex<'a> {
live: Option<char>,
inner: ::core::slice::Iter<'a, u8>,
}

impl<'a> Iterator for SliceToHex<'a> {
type Item = char;
ToHexIter::new(self.iter()).collect()
}
}

fn next(&mut self) -> Option<char> {
if let Some(live) = self.live.take() {
return Some(live);
}
impl<'a, T: ?Sized + ToHex> ToHex for &'a T {
fn to_hex<U: FromIterator<char>>(&self) -> U {
(**self).to_hex()
}
}

self.inner.next().map(|&byte| {
let current = CHARS[(byte >> 4) as usize] as char;
self.live = Some(CHARS[(byte & 0xf) as usize] as char);
current
})
}
/// An iterator converting byte slice to a hex string.
pub struct ToHexIter<T> {
live: Option<char>,
inner: T,
}

fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
impl<T> ToHexIter<T> {
pub fn new(inner: T) -> Self {
Self {
live: None,
inner,
}
}
}

impl<'a> iter::ExactSizeIterator for SliceToHex<'a> {
fn len(&self) -> usize {
let mut len = self.inner.len() * 2;
if self.live.is_some() {
len += 1;
}
len
}
impl<'a, T: Iterator<Item = &'a u8>> Iterator for ToHexIter<T> {
type Item = char;

fn next(&mut self) -> Option<char> {
if let Some(live) = self.live.take() {
return Some(live);
}

SliceToHex {
live: None,
inner: self.iter()
}.collect()
self.inner.next().map(|&byte| {
let current = CHARS[(byte >> 4) as usize] as char;
self.live = Some(CHARS[(byte & 0xf) as usize] as char);
current
})
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}

impl<'a, T: ?Sized + ToHex> ToHex for &'a T {
fn to_hex<U: FromIterator<char>>(&self) -> U {
(**self).to_hex()
impl<'a, T: iter::ExactSizeIterator + Iterator<Item = &'a u8>> iter::ExactSizeIterator for ToHexIter<T> {
fn len(&self) -> usize {
let mut len = self.inner.len() * 2;
if self.live.is_some() {
len += 1;
}
len
}
}

/// A trait for converting hexadecimal encoded values
pub trait FromHex {
/// Converts the value of `self`, interpreted as hexadecimal encoded data,
/// into an owned value constructed from an iterator of bytes.
Expand Down Expand Up @@ -196,9 +193,9 @@ impl FromHex for str {
buf <<= 4;

match byte {
b'A'...b'F' => buf |= byte - b'A' + 10,
b'a'...b'f' => buf |= byte - b'a' + 10,
b'0'...b'9' => buf |= byte - b'0',
b'A'..=b'F' => buf |= byte - b'A' + 10,
b'a'..=b'f' => buf |= byte - b'a' + 10,
b'0'..=b'9' => buf |= byte - b'0',
b' '|b'\r'|b'\n'|b'\t' => {
buf >>= 4;
continue
Expand Down

0 comments on commit 3df0b2e

Please sign in to comment.