zip_archive 1.2.2

Library that archive a directory with a specific compression format.
Documentation
use std::io;
use std::{
    ffi::{OsStr, OsString},
    fs::File,
    io::{Read, Write},
    path::{Path, PathBuf},
};

use xz2::write::XzEncoder;

use super::Compress;

fn append_ext(ext: impl AsRef<OsStr>, path: PathBuf) -> PathBuf {
    let mut os_string: OsString = path.into();
    os_string.push(".");
    os_string.push(ext.as_ref());
    os_string.into()
}

pub struct CompressXz;

impl Compress for CompressXz {
    fn compress<T: AsRef<Path>, O: AsRef<Path>>(origin: T, dest: O) -> Result<PathBuf, io::Error> {
        if !origin.as_ref().is_file() {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                "The origin is not a file!",
            ));
        }
        let mut origin_file = File::open(&origin)?;
        let mut dest = dest.as_ref().join(&origin.as_ref().file_name().unwrap());

        dest = append_ext("xz", dest);
        let dest_file = File::create(&dest)?;

        let mut encoder = XzEncoder::new(dest_file, 9);
        let mut content = Vec::new();
        origin_file.read_to_end(&mut content)?;
        encoder.write_all(&content)?;
        encoder.finish()?;
        return Ok(dest);
    }
}

#[cfg(test)]
mod tests {
    use function_name::named;

    use super::super::c_tar::CompressTar;
    use super::*;
    use crate::core::test_util::{cleanup, setup, Dir};

    #[test]
    #[named]
    fn compress_xz_test() {
        let Dir { origin, dest } = setup(function_name!());
        let tar_path = CompressTar::compress(&origin, &dest).unwrap();
        CompressXz::compress(&tar_path, dest).unwrap();

        assert!(tar_path.is_file());
        assert!(Path::new(&format!("{}.xz", &tar_path.to_str().unwrap())).is_file());
        cleanup(function_name!());
    }
}