diff options
author | Daniel Schadt <kingdread@gmx.de> | 2023-01-14 20:05:38 +0100 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2023-01-14 20:05:38 +0100 |
commit | ba171bad33767ad52e0900760358bac3df69f896 (patch) | |
tree | e82d81ae4cf0ebf12116367a68b870ee5c29a713 /src/gpx.rs | |
parent | 767b239776c23d9aa31c5d0b594ba200c430a8bb (diff) | |
download | hittekaart-ba171bad33767ad52e0900760358bac3df69f896.tar.gz hittekaart-ba171bad33767ad52e0900760358bac3df69f896.tar.bz2 hittekaart-ba171bad33767ad52e0900760358bac3df69f896.zip |
add support for reading brotli and gzip files
Diffstat (limited to 'src/gpx.rs')
-rw-r--r-- | src/gpx.rs | 42 |
1 files changed, 39 insertions, 3 deletions
@@ -3,9 +3,16 @@ //! We *could* use the [gpx](https://github.com/georust/gpx) crate, but we don't care about much //! other than the coordinates of the tracks. By implementing the little functionality ourselves, //! we can use a fast XML parser ([roxmltree](https://github.com/RazrFalcon/roxmltree)). -use std::{f64::consts::PI, fs, path::Path}; +use std::{ + f64::consts::PI, + ffi::OsStr, + fs::{self, File}, + io::{BufReader, Read}, + path::Path, +}; use color_eyre::eyre::{eyre, Result}; +use flate2::bufread::GzDecoder; use roxmltree::{Document, Node, NodeType}; #[derive(Debug, Copy, Clone, PartialEq)] @@ -67,12 +74,41 @@ pub fn extract_from_str(input: &str) -> Result<Vec<Coordinates>> { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Compression { None, + Gzip, + Brotli, +} + +impl Compression { + pub fn suggest_from_path<P: AsRef<Path>>(path: P) -> Option<Compression> { + let Some(ext) = path.as_ref().extension() else { return None }; + if OsStr::new("br") == ext { + Some(Compression::Brotli) + } else if [OsStr::new("gz"), OsStr::new("gzip")].contains(&ext) { + Some(Compression::Gzip) + } else if OsStr::new("gpx") == ext { + Some(Compression::None) + } else { + None + } + } } pub fn extract_from_file<P: AsRef<Path>>( path: P, - _compression: Compression, + compression: Compression, ) -> Result<Vec<Coordinates>> { - let content = fs::read_to_string(path)?; + let content = match compression { + Compression::None => fs::read_to_string(path)?, + Compression::Gzip => { + let mut result = String::new(); + GzDecoder::new(BufReader::new(File::open(path)?)).read_to_string(&mut result)?; + result + } + Compression::Brotli => { + let mut result = Vec::new(); + brotli::BrotliDecompress(&mut BufReader::new(File::open(path)?), &mut result)?; + String::from_utf8(result)? + } + }; extract_from_str(&content) } |