So a Read wrapper that can temporarily spawn a different wrapper on the same Read.
When R is a struct, everything is fine: ReadWrapper wraps the struct, and the OtherReadWrapper wraps a mut reference to the struct.
But when R is a Box<T> or a &mut T to begin with, the OtherReadWrapper now uselessly has to go an extra level of pointer indirection.
I can't think of a way to make this work without the extra level of pointer indirection while supporting both use cases of either a struct or a box/mut ref. Do I have a lack of imagination, or is it just not possible?
Unfortunately, the idea is to be able to continue using ReadWrapper once you're done with OtherReadWrapper. I guess one way to do that would be to make the OtherReadWrapper wrap ReadWrapper itself, but ReadWrapper is not Read (although the name could imply it, blame that on bad naming for this reduced usecase) so you'd then have to initialize OtherReadWrapper with a ReadWrapper, which would make testing more difficult.
I guess the simplest would be to have ReadWrapper just always wrap a &mut R in the first place.
The kind of usecase I have is that ReadWrapper handles a container format that comes from a Read (it's streamed), and the container format has internal parts, so OtherReadWrapper would be a struct representing those parts. ReadWrapper is kind of like an iterator that only allows to keep one item at a time. And some parts need to stream from the original Read.
One possibility is to do the following. However, I don't think it's a good thing to do (edit: or is it!?):
That loses the state of the ReadWrapper. To give a more concrete example of the sort of usecase, think of ReadWrapper as tar::Archive and OtherReadWrapper as tar::Entry. But the tar crate doesn't try to avoid the indirection when using Archive<&mut T>
I feel like this is the correct approach, however. Semantically, you keep a borrow of the reader. The fact that there is an impl<R: Read + ?Sized> Read for &mut R in std doesn't change the semantics of you wanting to mutably borrowing the reader (if I understand it right).
Maybe you can fix that by using a generic T: Deref<Target=R> + DerefMut instead of &mut R.
When you want to make the struct own the reader, you could use something akin to what I used here: Owned smart pointer. (Note this example is implementing Deref only, and not DerefMut.)
But I'm not sure if I fully overlook the issue right now (it's late here ).
I think Cow comes with some runtime-overhead, I guess? Because it's determined at runtime whether I deal with an owned value or with a reference (see also this post by me). That's why I used something like an Owned smart pointer in mmtkvdb. I wonder if it would make sense to add something like Owned to std. Is that very far-fetched? Maybe I should start a discussion on IRLO on that.
Update:
I just published a new crate deref_owned to provide such a smart pointer, which might aid further discussion regarding the usefulness or uselessness of such a data structure.