Apologies in advance, this is probably a trivial question, but I don't even know what to search for an answer. I want to read files that might or might not be zip compressed. Depending on the file extension, I need to either create a Reader from a simple io::File or from a BGZFReader<File>. Reader will be happy with anything that implements Read+Seek. The - non-working - code should look something like this:
let file_reader = if filename.as_ref().extension().unwrap_or_default() == "gz"
{
let in_file = BGZFReader::new(File::open(filename)?)?;
Reader::new(in_file)
}
else
{
let in_file = File::open(filename)?;
Reader::new(in_file)
};
But of course this doesn't work, because Reader<File> is not the same as Reader<BGZFReader<File>>. Is there a way to say that my variable file_reader can be any instance of Reader, irrespective of what exact implementation of Read+Seek I'm using?
The reason I want to define file_reader generically is because there are multiple files I need to open and then pass to the downstream code. Each could be compressed or not, so writing if/else statements for all possible combinations would become unmanageable very quickly.
Thanks to hints in the comments, I came up with this solution:
and downstream:
The two things I didn't understand initially were:
Boxing the inner file reader with adyntrait