You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.5 KiB

  1. use async_compression::tokio::bufread::{GzipDecoder, XzDecoder, ZstdDecoder};
  2. use clap::ArgEnum;
  3. use tokio::io::{AsyncRead, BufReader};
  4. #[derive(Copy, Clone, PartialEq, Ord, PartialOrd, Eq, ArgEnum, Debug)]
  5. pub enum CompressionMode {
  6. AUTO,
  7. NONE,
  8. ZSTD,
  9. GZIP,
  10. XZ,
  11. }
  12. impl CompressionMode {
  13. pub fn parse(filename: &str) -> Self {
  14. if filename.to_ascii_lowercase().ends_with("zst") {
  15. return Self::ZSTD;
  16. }
  17. if filename.to_ascii_lowercase().ends_with("zstd") {
  18. return Self::ZSTD;
  19. }
  20. if filename.to_ascii_lowercase().ends_with("xz") {
  21. return Self::XZ;
  22. }
  23. if filename.to_ascii_lowercase().ends_with("gz") {
  24. return Self::GZIP;
  25. }
  26. return Self::NONE;
  27. }
  28. }
  29. pub async fn get_decompressed_reader(
  30. compression_mode: CompressionMode,
  31. reader: Box<dyn AsyncRead + Unpin>,
  32. ) -> anyhow::Result<Box<dyn AsyncRead + Unpin>> {
  33. match compression_mode {
  34. CompressionMode::AUTO => unreachable!(),
  35. CompressionMode::NONE => Ok(Box::new(reader)),
  36. CompressionMode::ZSTD => {
  37. let reader = BufReader::new(reader);
  38. Ok(Box::new(ZstdDecoder::new(reader)))
  39. }
  40. CompressionMode::GZIP => {
  41. let reader = BufReader::new(reader);
  42. Ok(Box::new(GzipDecoder::new(reader)))
  43. }
  44. CompressionMode::XZ => {
  45. let reader = BufReader::new(reader);
  46. Ok(Box::new(XzDecoder::new(reader)))
  47. }
  48. }
  49. }