comtrya_lib/atoms/file/
remove.rs1use std::path::PathBuf;
2
3use tracing::error;
4
5use crate::atoms::{Atom, Outcome};
6
7use super::FileAtom;
8
9pub struct Remove {
10 pub target: PathBuf,
11}
12
13impl FileAtom for Remove {
14 fn get_path(&self) -> &std::path::PathBuf {
15 &self.target
16 }
17}
18
19impl std::fmt::Display for Remove {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 write!(f, "The file {} needs to be removed", self.target.display())
22 }
23}
24
25impl Atom for Remove {
26 fn plan(&self) -> anyhow::Result<crate::atoms::Outcome> {
27 if !self.target.is_file() {
28 error!(
29 "Cannot plan: target isn`t a file: {}",
30 self.target.display()
31 );
32
33 return Ok(Outcome {
34 side_effects: vec![],
35 should_run: false,
36 });
37 }
38
39 let metadata = self.target.parent().map(|p| p.metadata());
40
41 match metadata {
42 Some(v) => {
43 if v?.permissions().readonly() {
44 error!(
45 "Cannot plan: Dont have permission to delete {}",
46 self.target.display()
47 );
48
49 return Ok(Outcome {
50 side_effects: vec![],
51 should_run: false,
52 });
53 }
54 }
55 None => {
56 error!(
57 "Cannot plan: Failed to get parent directory of file: {}",
58 self.target.display()
59 );
60
61 return Ok(Outcome {
62 side_effects: vec![],
63 should_run: false,
64 });
65 }
66 };
67
68 Ok(Outcome {
69 side_effects: vec![],
70 should_run: true,
71 })
72 }
73
74 fn execute(&mut self) -> anyhow::Result<()> {
75 std::fs::remove_file(&self.target)?;
76 Ok(())
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use pretty_assertions::assert_eq;
84
85 #[test]
86 fn it_can_plan() {
87 let target_file = match tempfile::NamedTempFile::new() {
88 std::result::Result::Ok(file) => file,
89 std::result::Result::Err(_) => {
90 assert_eq!(false, true);
91 return;
92 }
93 };
94
95 let file_remove = Remove {
96 target: target_file.path().to_path_buf(),
97 };
98
99 assert_eq!(true, file_remove.plan().unwrap().should_run)
100 }
101
102 #[test]
103 fn it_can_execute() {
104 let target_file = match tempfile::NamedTempFile::new() {
105 std::result::Result::Ok(file) => file,
106 std::result::Result::Err(_) => {
107 assert_eq!(false, true);
108 return;
109 }
110 };
111
112 let mut file_remove = Remove {
113 target: target_file.path().to_path_buf(),
114 };
115
116 assert_eq!(true, file_remove.plan().unwrap().should_run);
117 assert_eq!(true, file_remove.execute().is_ok());
118 assert_eq!(false, file_remove.plan().unwrap().should_run)
119 }
120}