You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
1.8 KiB

use super::*;
use std::iter::{
FusedIterator,
Fuse,
};
pub struct HexStringIter<I>
{
ar: Fuse<I>,
hex1: u8,
}
impl<I> From<HexStringIter<I>> for String
where I: Iterator,
I::Item: Into<u8>
{
#[inline] fn from(from: HexStringIter<I>) -> Self
{
from.collect()
}
}
const fn gen_hex_table() -> [(u8, u8); 256]
{
let mut res = [(0, 0); 256];
let mut i =0;
const HEX: &'static [u8] = b"0123456789abcdef";
while i < 256 {
let by = i as u8;
res[i] = (HEX[(by >> 4) as usize], HEX[(by & 0xf) as usize]);
i+=1;
}
res
}
static HEX_TABLE: [(u8, u8); 256] = gen_hex_table();
impl<I> Iterator for HexStringIter<I>
where I: Iterator,
I::Item: Into<u8>
{
type Item = char;
fn next(&mut self) -> Option<Self::Item>
{
if self.hex1 != 0 {
return Some(std::mem::replace(&mut self.hex1, 0) as char);
}
let by = self.ar.next()?.into();
let (h0, h1) = HEX_TABLE[by as usize];
self.hex1 = h1;
Some(h0 as char)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (s, l) = self.ar.size_hint();
(s * 2, l.map(|x| x*2))
}
}
impl<I> ExactSizeIterator for HexStringIter<I>
where I: Iterator + ExactSizeIterator,
I::Item: Into<u8>{}
impl<I> FusedIterator for HexStringIter<I>
where I: Iterator,
I::Item: Into<u8>{}
pub trait HexStringIterExt<I>: Sized
{
fn hex_string(self) -> HexStringIter<I>;
}
impl<I> HexStringIterExt<I::IntoIter> for I
where I: IntoIterator,
I::Item: Into<u8>
{
#[inline] fn hex_string(self) -> HexStringIter<I::IntoIter> {
HexStringIter {
ar: self.into_iter().fuse(),
hex1: 0,
}
}
}
pub trait HexStringSliceExt
{
fn to_hex_string(&self) -> String;
}
impl<T> HexStringSliceExt for T
where T: AsRef<[u8]>
{
fn to_hex_string(&self) -> String {
self.as_ref().iter().copied().hex_string().collect()
}
}