I'm trying to implement a support for OSM XML files, and they may come in several compressed formats, or just plain uncompressed XML:
-
*.osm
(plain XML) should be opened withstd::io::BufReader
, -
*.osm.gz
(same gzipped) becomesflate2::write::ZlibDecoder
-
*.osm.bz2
becomesbzip2::Decompress
- etc.
So I must declare parser type from xml-rs, right away with a nested type:
let parser: EventReader<Decoder<File>>;
match file_extension {
".osm" => { parser = EventReader::new(File::new(...)) },
".osm.gz" => { parser = EventReader::new(ZlibDecoder(...)) },
...
But this won't compile, and I can't put let
in match clauses, because of scoping.
I thought I'd make a wrapper enum
type, but it seems that I need to implement Read
and BufRead
traits, which is quite a lot of code.
What are other options?
I'm thinking of declaring a function with a generic type. Will this work?
fn parse_xml(rd: EventReader<R>)
where R: Read {
// do parse
}
let file = File::open(input_path)?;
match my_file_type {
".osm" => { parse_xml(EventReader::new(BufReader(file)) },
".osm.gz" => { parse_xml(EventReader::new(ZlibDecoder(file)) },
".osm.bz2" => { parse_xml(EventReader::new(Decompress(file)) }
_ => { return Err("unsupported format".into()) }
}