I'm writing a Rust implementation of the Google Brotli decompression algorithm, which uses a fixed number of "implicit zeroes" at the end of the stream to enable certain optimisations.
The Google C implementation does this using a spaghetti code of various counters, but I'd like to use the adaptors in the Rust std::io library instead. Something like:
pub struct StreamBitReader<R> {
reader: Chain<R,Take<Repeat>>,
...
}
where 'R' is the underlying Read
that the bit reader struct is wrapping. However, there are a number of cases where the decompression algorithm checks to see if it has "overrun" the stream, and it does this by checking the number of implicit zero bytes read. This appears to be impossible in safe Rust, as there is no way to obtain a reference to the components of Chain
, unless I'm missing something.
When Chain
is constructed, it takes ownership of (moves) the underlying Read
structs, which then are hidden in private members.
Is there any way to construct the Take<Repeat>
part such that I can access the limit()
fn of Take
even after the Chain
adaptor takes ownership?
I know of one way, but I don't think it will suit your goal.
The key being
Read::by_ref
, which returns a mutable reference.Read
is implemented for any mutable reference to a type that implementsRead
, so you can give ownership of the reference toChain
.The trick is that you have to destroy the
Chain
before you can use the inner object again. It would also be very painful / impossible to store this in the struct.Your best bet might be to write your own
ZeroPadded
adapter that combinesChain
,Repeat
, andTake
and provides thelimit
method.If no one else gives better answers, I could also see adding a feature request for methods on the adapters. It's not uncommon to have a
into_inner
method that consumes an adapter and gives back the wrapped item, but you could also have anas_inner
that returns a reference to the wrapped object.