archiver_rs/
xz.rs

1#[cfg(feature = "xz")]
2pub use self::xz::Xz;
3
4#[cfg(feature = "xz")]
5mod xz {
6    use std::fs::{create_dir_all, File};
7    use std::io::{copy, Read};
8    use std::path::Path;
9
10    use xz2::read::XzDecoder;
11
12    use crate::{Compressed, Result};
13
14    pub struct Xz<R: Read> {
15        archive: XzDecoder<R>,
16    }
17
18    impl Xz<File> {
19        pub fn open(path: &Path) -> std::io::Result<Self> {
20            let archive = File::open(path)?;
21
22            Self::new(archive)
23        }
24    }
25
26    impl<R: Read> Xz<R> {
27        pub fn new(r: R) -> std::io::Result<Self> {
28            let archive = XzDecoder::new(r);
29
30            Ok(Self { archive })
31        }
32    }
33
34    impl<R: Read> Compressed for Xz<R> {
35        fn decompress(&mut self, target: &Path) -> Result<()> {
36            if let Some(p) = target.parent() {
37                if !p.exists() {
38                    create_dir_all(&p)?;
39                }
40            }
41
42            let mut output = File::create(target)?;
43            copy(&mut self.archive, &mut output)?;
44
45            Ok(())
46        }
47    }
48
49    impl<R: Read> Read for Xz<R> {
50        fn read(&mut self, into: &mut [u8]) -> std::io::Result<usize> {
51            self.archive.read(into)
52        }
53    }
54}