I’m working on a parser for a packet-based file format. The different packets are processed by different functions To get at the actual data, I pass in a
std::io:Error. I’ve considered three different approaches, but each has issues.
Currently, I’m passing around a
&mut std::io::read, i.e., something like:
fn foo_process(reader: &mut T) -> Result<Foo, std::io::Error>
But, this apprears to be incompatible with flate2’s expectations, which appears to want to own the
std::io::Read. (Or, I can’t figure out how to get it to work. Example code here: https://play.rust-lang.org/?gist=217ad42f5aac811a4ea4d4113ff40ee0&version=stable ).
std::io::Readobect into the function solves that problem, but, then I have to worry about returning it and the deserialized packet, i.e., something like:
fn foo_process(reader: T) -> Result<(Foo, T), std::io::Error>
Which is ugly.
I’ve also played with boxed trait objects:
fn foo_process(reader: Boxstd::io::Read) -> Result<Foo, std::io::Error);
But this approach clutters the code with lots of boxing and unboxing, has a few
Sized issues, which require some acrobatics, and has a small performance cost, which I don’t think is significant for this code. Although, I’ve come furthest with this approach, I suspect it is less idomatic.
So, my question is: should I be passing around references, moving objects, or using boxes?