SHARE
TWEET

Untitled

a guest Apr 20th, 2019 92 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #[macro_use]
  2. extern crate rental;
  3.  
  4. use flate2::read::GzDecoder;
  5. use std::fs::File;
  6. use std::io;
  7. use std::io::Read;
  8. use tar::Archive;
  9. use tar::Entry;
  10.  
  11. type Reader = Box<dyn Read>;
  12. type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
  13.  
  14. rental! {
  15.     mod rentals {
  16.         use super::*;
  17.  
  18.         #[rental_mut]
  19.         pub struct Inner {
  20.             archive: Box<Archive<Reader>>,
  21.             entry: Entry<'archive, Reader>,
  22.         }
  23.     }
  24. }
  25.  
  26. struct ArchiveFile {
  27.     inner: rentals::Inner,
  28. }
  29.  
  30. fn find_entry<'a>(archive: &'a mut Archive<Reader>, file: &str) -> Result<Entry<'a, Reader>> {
  31.     for entry in archive.entries()? {
  32.         let entry = entry?;
  33.         if entry.path()?.to_string_lossy() == file {
  34.             return Ok(entry);
  35.         }
  36.     }
  37.  
  38.     Err(Box::new(io::Error::new(
  39.         io::ErrorKind::NotFound,
  40.         "File not found in archive",
  41.     )))
  42. }
  43.  
  44. impl ArchiveFile {
  45.     pub fn open(archive: &str, file: &str) -> Result<Self> {
  46.         let reader: Reader = Box::new(GzDecoder::new(File::open(archive)?));
  47.         let archive = Archive::new(reader);
  48.  
  49.         let inner = rentals::Inner::try_new(Box::new(archive), |arc| find_entry(arc, file))
  50.             .map_err(|e| e.0)?;
  51.  
  52.         Ok(ArchiveFile { inner })
  53.     }
  54. }
  55.  
  56. impl Read for ArchiveFile {
  57.     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
  58.         self.inner.rent_mut(|entry| entry.read(buf))
  59.     }
  60. }
  61.  
  62. fn main() {
  63.     let mut file = ArchiveFile::open("a.tar.gz", "a/file1").unwrap();
  64.  
  65.     let mut data = String::new();
  66.     file.read_to_string(&mut data).unwrap();
  67.  
  68.     dbg!(data);
  69. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top