1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use std::marker::PhantomData; use list_fn::{List, ListFn, FlatScan, FlatScanListFn, FlatScanEx, Empty}; use uints::UInt; pub struct Lsb0<T: UInt> { value: T, size: u8, } impl<T: UInt> Lsb0<T> { fn new(value: T) -> Self { Self { value, size: T::BITS, } } } impl<T: UInt> ListFn for Lsb0<T> { type Item = bool; type End = Lsb0ListFn<T>; fn list(self) -> List<Self> { match self.size { 0 => List::End(Default::default()), size => List::Some( self.value & T::ONE != T::ZERO, Self { value: self.value >> 1, size: size - 1, }, ), } } } pub struct Lsb0ListFn<T: UInt>(PhantomData<T>); impl<T: UInt> Default for Lsb0ListFn<T> { fn default() -> Self { Self ( Default::default() ) } } impl<T: UInt> FlatScan for Lsb0ListFn<T> { type InputItem = T; type ItemList = Lsb0<T>; type EndList = Empty<bool>; fn item(self, item: T) -> Lsb0<T> { Lsb0::new(item) } fn end(self) -> Empty<bool> { Default::default() } } pub trait BitsEx: ListFn where Self::Item: UInt { fn lsb0(self) -> FlatScanListFn<Self, Lsb0ListFn<Self::Item>> { self.flat_scan(Default::default()) } } impl<L: ListFn> BitsEx for L where Self::Item: UInt {} #[cfg(test)] mod tests { use super::*; use list_fn::Collect; #[test] fn it_works() { let a: &[u8] = &[1, 2]; assert_eq!( a.iter().cloned().lsb0().collect(), vec!( true, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false ) ); let v: Vec<u8> = vec![3, 4]; assert_eq!( v.into_iter().lsb0().collect(), vec!( true, true, false, false, false, false, false, false, false, false, true, false, false, false, false, false ) ); } }