I want to create a function which returns a BufReader<R>, but R is not known at compile time. More precisely, R could be a File, a GzDecoder<File> or any other compression decoder.
I guess returning an impl Trait won't work. So what should I use ? Trait objects ?
@alice Thanks for your suggestions. I can see with enum but for the trait object, its not clear to me. Is it just a matter of Box<dyn Read> as the return type from the function ?
I can return a Box<syn Read> but I can't figure out how to use it with regular BufReader methods:
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub enum CompressionScheme {
Gzip,
Bzip2,
Xz,
NotCompressed,
}
impl CompressionScheme {
/// True if this matches any of the valid compression scheme
#[inline(always)]
pub fn is_compressed(&self) -> bool {
self != &CompressionScheme::NotCompressed
}
fn reader(&self, path: &PathBuf) -> Box<dyn Read> {
// open target file
let file = File::open(&path).expect("unable to open file");
// if file is compressed, we need to call a specific reader
if self.is_compressed() {
let decoder = GzDecoder::new(file);
let reader = BufReader::new(decoder);
Box::new(reader)
} else {
let reader = BufReader::new(file);
Box::new(reader)
}
}
}