diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gpx.rs | 42 | ||||
| -rw-r--r-- | src/main.rs | 8 | 
2 files changed, 45 insertions, 5 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)  } diff --git a/src/main.rs b/src/main.rs index f4a7aa7..e2dacb7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use std::{  };  use clap::Parser; -use color_eyre::eyre::{bail, Context, Result}; +use color_eyre::eyre::{bail, eyre, Context, Result};  use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle};  use is_terminal::IsTerminal;  use rayon::ThreadPoolBuilder; @@ -14,6 +14,8 @@ mod gpx;  mod layer;  mod renderer; +use gpx::Compression; +  #[derive(Parser, Debug, Clone)]  #[command(author, version, about)]  struct Args { @@ -70,7 +72,9 @@ fn main() -> Result<()> {      let mut tracks = Vec::new();      for file in &args.files { -        let data = gpx::extract_from_file(file, gpx::Compression::None).unwrap(); +        let compression = Compression::suggest_from_path(file) +            .ok_or_else(|| eyre!("Could not determine format for {file:?}"))?; +        let data = gpx::extract_from_file(file, compression)?;          tracks.push(data);          bar.inc(1);      }  | 
