use std;
pub type Dibits<T> = SubByteIter<DibitParams, T>;
pub type Tribits<T> = SubByteIter<TribitParams, T>;
pub type Hexbits<T> = SubByteIter<HexbitParams, T>;
pub type DibitBytes<T> = SubByteIter<DibitByteParams, T>;
pub type TribitBytes<T> = SubByteIter<TribitByteParams, T>;
pub type HexbitBytes<T> = SubByteIter<HexbitByteParams, T>;
pub trait IterParams {
type Input;
type Output;
fn bits() -> usize;
fn buffer() -> usize;
fn shift() -> usize;
fn post_shift() -> usize {
32 - Self::shift() * Self::buffer()
}
fn iterations() -> usize {
Self::shift() * Self::buffer() / Self::bits()
}
fn to_byte(input: Self::Input) -> u8;
fn to_output(bits: u8) -> Self::Output;
fn validate() {
assert!(Self::buffer() * Self::shift() <= 32);
}
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct Dibit(u8);
impl Dibit {
pub fn new(bits: u8) -> Dibit {
assert!(bits >> 2 == 0);
Dibit(bits)
}
pub fn bits(&self) -> u8 {
self.0
}
pub fn hi(&self) -> u8 {
self.0 >> 1
}
pub fn lo(&self) -> u8 {
self.0 & 1
}
}
pub struct DibitParams;
impl IterParams for DibitParams {
type Input = u8;
type Output = Dibit;
fn bits() -> usize {
2
}
fn buffer() -> usize {
1
}
fn shift() -> usize {
8
}
fn to_byte(input: Self::Input) -> u8 {
input
}
fn to_output(bits: u8) -> Dibit {
Dibit::new(bits)
}
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct Tribit(u8);
impl Tribit {
pub fn new(bits: u8) -> Tribit {
assert!(bits >> 3 == 0);
Tribit(bits)
}
pub fn bits(&self) -> u8 {
self.0
}
}
pub struct TribitParams;
impl IterParams for TribitParams {
type Input = u8;
type Output = Tribit;
fn bits() -> usize {
3
}
fn buffer() -> usize {
3
}
fn shift() -> usize {
8
}
fn to_byte(input: Self::Input) -> u8 {
input
}
fn to_output(bits: u8) -> Tribit {
Tribit::new(bits)
}
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq)]
pub struct Hexbit(u8);
impl Hexbit {
pub fn new(bits: u8) -> Hexbit {
assert!(bits >> 6 == 0);
Hexbit(bits)
}
pub fn bits(&self) -> u8 {
self.0
}
}
pub struct HexbitParams;
impl IterParams for HexbitParams {
type Input = u8;
type Output = Hexbit;
fn bits() -> usize {
6
}
fn buffer() -> usize {
3
}
fn shift() -> usize {
8
}
fn to_byte(input: Self::Input) -> u8 {
input
}
fn to_output(bits: u8) -> Hexbit {
Hexbit::new(bits)
}
}
pub struct DibitByteParams;
impl IterParams for DibitByteParams {
type Input = Dibit;
type Output = u8;
fn bits() -> usize {
8
}
fn buffer() -> usize {
4
}
fn shift() -> usize {
2
}
fn to_byte(input: Self::Input) -> u8 {
input.bits()
}
fn to_output(bits: u8) -> Self::Output {
bits
}
}
pub struct TribitByteParams;
impl IterParams for TribitByteParams {
type Input = Tribit;
type Output = u8;
fn bits() -> usize {
8
}
fn buffer() -> usize {
8
}
fn shift() -> usize {
3
}
fn to_byte(input: Self::Input) -> u8 {
input.bits()
}
fn to_output(bits: u8) -> Self::Output {
bits
}
}
pub struct HexbitByteParams;
impl IterParams for HexbitByteParams {
type Input = Hexbit;
type Output = u8;
fn bits() -> usize {
8
}
fn buffer() -> usize {
4
}
fn shift() -> usize {
6
}
fn to_byte(input: Self::Input) -> u8 {
input.bits()
}
fn to_output(bits: u8) -> Self::Output {
bits
}
}
pub struct SubByteIter<P, T>
where
P: IterParams,
T: Iterator<Item = P::Input>,
{
params: std::marker::PhantomData<P>,
src: T,
buf: u32,
idx: u8,
}
impl<P, T> SubByteIter<P, T>
where
P: IterParams,
T: Iterator<Item = P::Input>,
{
pub fn new(src: T) -> SubByteIter<P, T> {
SubByteIter {
params: std::marker::PhantomData,
src,
buf: 0,
idx: 0,
}
}
fn buffer(&mut self) -> Option<u32> {
let (buf, added) = (&mut self.src)
.take(P::buffer())
.fold((0, 0), |(buf, added), next| {
(buf << P::shift() | P::to_byte(next) as u32, added + 1)
});
if added == 0 {
return None;
}
assert!(added == P::buffer(), "incomplete source");
Some(buf << P::post_shift())
}
}
impl<P, T> Iterator for SubByteIter<P, T>
where
P: IterParams,
T: Iterator<Item = P::Input>,
{
type Item = P::Output;
fn next(&mut self) -> Option<Self::Item> {
if self.idx == 0 {
self.buf = match self.buffer() {
Some(b) => b,
None => return None,
};
}
let bits = self.buf >> (32 - P::bits());
self.buf <<= P::bits();
self.idx += 1;
self.idx %= P::iterations() as u8;
Some(P::to_output(bits as u8))
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn validate_params() {
DibitParams::validate();
TribitParams::validate();
HexbitParams::validate();
DibitByteParams::validate();
TribitByteParams::validate();
HexbitByteParams::validate();
}
#[test]
fn test_dibits() {
let bytes = [0b00110011, 0b10011001, 0b11111111];
let mut d = Dibits::new(bytes.iter().cloned());
assert_eq!(d.next().unwrap().bits(), 0b00);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert_eq!(d.next().unwrap().bits(), 0b00);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert_eq!(d.next().unwrap().bits(), 0b10);
assert_eq!(d.next().unwrap().bits(), 0b01);
assert_eq!(d.next().unwrap().bits(), 0b10);
assert_eq!(d.next().unwrap().bits(), 0b01);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert_eq!(d.next().unwrap().bits(), 0b11);
assert!(d.next().is_none());
}
#[test]
fn test_dibit_bytes() {
let dibits = [
Dibit::new(0b00),
Dibit::new(0b11),
Dibit::new(0b00),
Dibit::new(0b11),
Dibit::new(0b10),
Dibit::new(0b01),
Dibit::new(0b10),
Dibit::new(0b01),
Dibit::new(0b11),
Dibit::new(0b11),
Dibit::new(0b11),
Dibit::new(0b11),
];
let mut d = DibitBytes::new(dibits.iter().cloned());
assert_eq!(d.next().unwrap(), 0b00110011);
assert_eq!(d.next().unwrap(), 0b10011001);
assert_eq!(d.next().unwrap(), 0b11111111);
assert!(d.next().is_none());
}
#[test]
#[should_panic]
fn test_dibit_bytes_panic() {
let dibits = [
Dibit::new(0b00),
Dibit::new(0b11),
Dibit::new(0b00),
Dibit::new(0b11),
Dibit::new(0b10),
];
let mut d = DibitBytes::new(dibits.iter().cloned());
d.next();
d.next();
}
#[test]
fn test_tribits() {
let bytes = [
0b00101001, 0b11001011, 0b10111000, 0b00101001, 0b11001011, 0b10111000,
];
let mut t = Tribits::new(bytes.iter().cloned());
assert_eq!(t.next().unwrap().bits(), 0b001);
assert_eq!(t.next().unwrap().bits(), 0b010);
assert_eq!(t.next().unwrap().bits(), 0b011);
assert_eq!(t.next().unwrap().bits(), 0b100);
assert_eq!(t.next().unwrap().bits(), 0b101);
assert_eq!(t.next().unwrap().bits(), 0b110);
assert_eq!(t.next().unwrap().bits(), 0b111);
assert_eq!(t.next().unwrap().bits(), 0b000);
assert_eq!(t.next().unwrap().bits(), 0b001);
assert_eq!(t.next().unwrap().bits(), 0b010);
assert_eq!(t.next().unwrap().bits(), 0b011);
assert_eq!(t.next().unwrap().bits(), 0b100);
assert_eq!(t.next().unwrap().bits(), 0b101);
assert_eq!(t.next().unwrap().bits(), 0b110);
assert_eq!(t.next().unwrap().bits(), 0b111);
assert_eq!(t.next().unwrap().bits(), 0b000);
assert!(t.next().is_none());
}
#[test]
#[should_panic]
fn test_tribits_panic() {
let bytes = [1, 2, 3, 4];
let t = Tribits::new(bytes.iter().cloned());
for _ in t {}
}
#[test]
fn test_tribit_bytes() {
let tribits = [
Tribit::new(0b001),
Tribit::new(0b010),
Tribit::new(0b011),
Tribit::new(0b100),
Tribit::new(0b101),
Tribit::new(0b110),
Tribit::new(0b111),
Tribit::new(0b000),
Tribit::new(0b001),
Tribit::new(0b010),
Tribit::new(0b011),
Tribit::new(0b100),
Tribit::new(0b101),
Tribit::new(0b110),
Tribit::new(0b111),
Tribit::new(0b000),
];
let mut t = TribitBytes::new(tribits.iter().cloned());
assert_eq!(t.next().unwrap(), 0b00101001);
assert_eq!(t.next().unwrap(), 0b11001011);
assert_eq!(t.next().unwrap(), 0b10111000);
assert_eq!(t.next().unwrap(), 0b00101001);
assert_eq!(t.next().unwrap(), 0b11001011);
assert_eq!(t.next().unwrap(), 0b10111000);
assert!(t.next().is_none());
}
#[test]
#[should_panic]
fn test_tribit_bytes_panic() {
let tribits = [
Tribit::new(0b001),
Tribit::new(0b010),
Tribit::new(0b011),
Tribit::new(0b100),
];
let mut t = TribitBytes::new(tribits.iter().cloned());
t.next();
t.next();
}
#[test]
fn test_hexbits() {
let bytes = [
0b11111100, 0b00001010, 0b10010101, 0b11111100, 0b00001010, 0b10010101,
];
let mut h = Hexbits::new(bytes.iter().cloned());
assert_eq!(h.next().unwrap().bits(), 0b111111);
assert_eq!(h.next().unwrap().bits(), 0b000000);
assert_eq!(h.next().unwrap().bits(), 0b101010);
assert_eq!(h.next().unwrap().bits(), 0b010101);
assert_eq!(h.next().unwrap().bits(), 0b111111);
assert_eq!(h.next().unwrap().bits(), 0b000000);
assert_eq!(h.next().unwrap().bits(), 0b101010);
assert_eq!(h.next().unwrap().bits(), 0b010101);
assert!(h.next().is_none());
}
#[test]
#[should_panic]
fn test_hexbits_panic() {
let bytes = [0b11111100, 0b00001010];
let mut h = Hexbits::new(bytes.iter().cloned());
assert_eq!(h.next().unwrap().bits(), 0b111111);
assert_eq!(h.next().unwrap().bits(), 0b000000);
h.next();
}
#[test]
fn test_hexbit_bytes() {
let hexbits = [
Hexbit::new(0b111111),
Hexbit::new(0b000000),
Hexbit::new(0b101010),
Hexbit::new(0b010101),
Hexbit::new(0b111111),
Hexbit::new(0b000000),
Hexbit::new(0b101010),
Hexbit::new(0b010101),
];
let mut h = HexbitBytes::new(hexbits.iter().cloned());
assert_eq!(h.next().unwrap(), 0b11111100);
assert_eq!(h.next().unwrap(), 0b00001010);
assert_eq!(h.next().unwrap(), 0b10010101);
assert_eq!(h.next().unwrap(), 0b11111100);
assert_eq!(h.next().unwrap(), 0b00001010);
assert_eq!(h.next().unwrap(), 0b10010101);
assert!(h.next().is_none());
}
#[test]
#[should_panic]
fn test_hexbit_bytes_panic() {
let hexbits = [
Hexbit::new(0b111111),
Hexbit::new(0b000000),
Hexbit::new(0b101010),
Hexbit::new(0b010101),
Hexbit::new(0b111111),
];
let mut h = HexbitBytes::new(hexbits.iter().cloned());
h.next();
h.next();
h.next();
h.next();
h.next();
h.next();
}
}