I have this code:
pub trait BytesToBits<T>: Iterator<Item = u8>
where
T: Iterator<Item = bool>,
{
fn bits(&mut self) -> T;
}
impl<T> BytesToBits<T> for dyn Iterator<Item = u8>
where
T: Iterator<Item = bool>,
{
fn bits(&mut self) -> T {
self.flat_map(|byte| (0..8).map(move |offset| byte & (1 << offset) != 0))
}
}
However, compiling it results in:
error[E0308]: mismatched types
--> src/bitstream.rs:13:9
|
8 | impl<T> BytesToBits<T> for dyn Iterator<Item = u8>
| - this type parameter
...
12 | fn bits(&mut self) -> T {
| - expected `T` because of return type
13 | self.flat_map(|byte| (0..8).map(move |offset| byte & (1 << offset) != 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `FlatMap`
|
= note: expected type parameter `T`
found struct `FlatMap<&mut (dyn Iterator<Item = u8> + 'static), Map<std::ops::Range<{integer}>, [closure@src/bitstream.rs:13:41: 13:54]>, [closure@src/bitstream.rs:13:23: 13:29]>`
I am new to Rust and do not know what I exactly did wrong there and how to resolve the issue.
My goal is to have a trait BytesToBits
that extends all Iterator<Item = u8>
by providing them with a method bits()
that returns an Iterator<Item = bool>
.
Thanks for the comments and the answer. I think my issue again boiled down to the fact, that you cannot return traits from functions of traits [1]. I solved it now with a custom iterator:
pub trait BytesToBits<T>
where
T: Iterator<Item = bool>,
{
fn bits(self) -> T;
}
impl<T> BytesToBits<BytesToBitsIterator<T>> for T
where
T: Iterator<Item = u8>,
{
fn bits(self) -> BytesToBitsIterator<T> {
BytesToBitsIterator::from(self)
}
}
pub struct BytesToBitsIterator<T>
where
T: Iterator<Item = u8>,
{
bytes: T,
current: Option<u8>,
index: u8,
}
impl<T> From<T> for BytesToBitsIterator<T>
where
T: Iterator<Item = u8>,
{
fn from(bytes: T) -> Self {
Self {
bytes,
current: None,
index: 0,
}
}
}
impl<T> Iterator for BytesToBitsIterator<T>
where
T: Iterator<Item = u8>,
{
type Item = bool;
fn next(&mut self) -> Option<Self::Item> {
if self.index > 7 {
self.current = None;
self.index = 0;
}
let current = match self.current {
None => match self.bytes.next() {
None => {
return None;
}
Some(byte) => {
self.current = Some(byte);
byte
}
},
Some(byte) => byte,
};
let bit = current & (1 << self.index) != 0;
self.index += 1;
Some(bit)
}
}