I'm trying to make struct that wraps quick_xml::Reader, with a generic structure inside, which must have BufRead trait.
I need 2 extra structures:
-
quick_xml::Reader requires
BufRead
trait, - I want to have a File, Gzip Reader, or Bzip2 reader inside
So the structure has to be like this: a BufReader
with dyn Read
in a box:
OsmParser<quick_xml::Reader<BufReader<Box<dyn BufRead>>>
But defining it this way doesn't work:
pub struct OsmParser<R: BufRead> {
rd: Reader<BufReader<Box<R>>>
}
impl <R: BufRead> OsmParser<R> {
fn new(rd: R) -> OsmParser<Reader<BufReader<Box<R>>>> {
error[E0277]: the trait bound `Reader<BufReader<Box<R>>>: BufRead` is not satisfied
--> src/main.rs:27:19
|
27 | fn new(rd: R) -> OsmParser<Reader<BufReader<Box<R>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `BufRead` is not implemented for `Reader<BufReader<Box<R>>>`
Trying to fix it, I got this error, and don't know what to do:
pub struct OsmParser<R: Read> {
rd: Reader<BufReader<Box<R>>>
}
impl <R: Read> OsmParser<R> {
fn new(rd: BufReader<Box<R>>) -> OsmParser<R> {
Self {rd: Reader::from_reader(rd)}
}
fn from_path(path: String) -> Result<OsmParser<R>> {
let rd = {
...
match &cap2[2] {
".gz" => Box::new(GzDecoder::new(fp)?) as Box<dyn Read>,
".bz2" => Box::new(BzDecoder::new(fp)) as Box<dyn Read>,
_ => Box::new(fp) as Box<dyn Read>
}
};
let reader = BufReader::new(rd);
Ok(Self::new(reader))
}
}
25 | impl <R: Read> OsmParser<R> {
| - this type parameter
...
48 | Ok(Self::new(reader))
| ^^^^^^ expected type parameter `R`, found trait object `dyn std::io::Read`
|
= note: expected struct `BufReader<Box<R>>`
found struct `BufReader<Box<dyn std::io::Read>>`
Tried adding where R: Read
to new
or from_path
just for luck, but it doesn't help.
- How do I fix it?
- Is this stack of nested types a proper way to do this?