comtrya_lib/atoms/file/
unarchive.rs

1use std::{fs::File, path::PathBuf};
2
3use flate2::read::GzDecoder;
4use tar::Archive;
5
6use crate::atoms::{Atom, Outcome};
7
8use super::FileAtom;
9
10pub struct Unarchive {
11    pub origin: PathBuf,
12    pub dest: PathBuf,
13    pub force: bool,
14}
15
16impl FileAtom for Unarchive {
17    fn get_path(&self) -> &PathBuf {
18        &self.origin
19    }
20}
21
22impl Atom for Unarchive {
23    // Determine if this atom needs to run
24    fn plan(&self) -> anyhow::Result<Outcome> {
25        if self.dest.exists() {
26            if self.force {
27                return Ok(Outcome {
28                    side_effects: vec![],
29                    should_run: self.origin.exists(),
30                });
31            }
32            return Ok(Outcome {
33                side_effects: vec![],
34                should_run: false,
35            });
36        }
37
38        Ok(Outcome {
39            side_effects: vec![],
40            should_run: self.origin.exists(),
41        })
42    }
43
44    // Apply new to old
45    fn execute(&mut self) -> anyhow::Result<()> {
46        let tar_gz = File::open(&self.origin)?;
47        let tar = GzDecoder::new(tar_gz);
48        let mut archive = Archive::new(tar);
49        archive.unpack(&self.dest)?;
50        Ok(())
51    }
52}
53
54impl std::fmt::Display for Unarchive {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        let origin_path = self.origin.display().to_string();
57        let dest_path = self.dest.display().to_string();
58
59        write!(
60            f,
61            "The archive {} to be decompressed to {}",
62            origin_path, dest_path
63        )
64    }
65}