How to pass io::Bytes to an adapter that expects Iterator<Item=u8> but still handle any errors?

I have an std::io::Bytes iterator that I want to pass to an iterator adapter that requires Iterator<Item=u8>. But I also want to handle any error. How can I do this?

My current method is to create another iterator adapter that performs the conversion and saves the error. It looks something like this:

// Adapts the iterator item from Result<u8> to u8
pub struct Adapter<I, E>
where I: Iterator<Item=Result<u8, E>>
{
    iter: I,
    error: Option<E>
}
impl<I, E> Iterator for Adapter<I, E> 
where I: Iterator<Item=Result<u8, E>>
{
    type Item = u8;
    fn next(&mut self) -> Option<Self::Item> {
        // implementation goes here
    }
}

If there’s an error the iteration is stopped and the error condition can be checked. However there’s no way to ensure the error is actually checked.

You can’t directly, because Iterator<Item=u8> by definition it doesn’t have a concept of a failure.

  • You can panic, risking aborting the entire thread or program.
  • You can return None from the iterator (and fail silently)
  • You can buffer all data ahead of time, handling all errors, and then create create an iterator once all data has loaded successfully.
  • You can signal an error during iteration out of band.

The last option would be something like a field on Adapter has_failed that you’d expect Adapter-aware callers to check. The callers that are only aware of the Iterator trait won’t, and there’s no way around that, because Iterator sort-of guarantees it won’t fail.

Thanks. I might experiment with alternative ways. Perhaps your third option would be the most robust.