atomic_ops/process/file/
copy.rs1use std::{
2 path::{Path, PathBuf},
3 sync::Arc,
4};
5
6use serde::{Deserialize, Serialize};
7use serde_flow::encoder::{bincode, FlowEncoder};
8
9use crate::{
10 error::{OpsError, OpsResult},
11 operation::LoaderFn,
12 process::{constants::COPY_FILE_ID, Process},
13};
14
15const COPY_REMOVE_FILE: &str = "cp_rm";
16
17#[derive(Serialize, Deserialize, Default)]
18pub struct Op {
19 from: PathBuf,
20 to: PathBuf,
21
22 #[serde(skip)]
23 bytes: Vec<u8>,
24}
25
26impl Op {
27 pub fn new(from: &Path, to: &Path) -> OpsResult<Self> {
28 let mut object = Self {
29 from: from.to_path_buf(),
30 to: to.to_path_buf(),
31 bytes: Vec::new(),
32 };
33 object.bytes =
34 bincode::Encoder::serialize(&object).map_err(|_| OpsError::SerializeFailed)?;
35 Ok(object)
36 }
37
38 pub fn from_bytes(bytes: &[u8]) -> OpsResult<Self> {
39 let mut decoded: Op =
40 bincode::Encoder::deserialize(bytes).map_err(|_| OpsError::SerializeFailed)?;
41 decoded.bytes = bytes.to_vec();
42 Ok(decoded)
43 }
44}
45
46pub fn load(bytes: &[u8]) -> OpsResult<Box<dyn Process>> {
47 let value = Op::from_bytes(bytes)?;
48 Ok(Box::new(value))
49}
50
51pub fn loader() -> (u8, LoaderFn) {
52 (COPY_FILE_ID, Arc::new(load))
53}
54
55impl Process for Op {
56 #[inline]
57 fn prepare(&self) -> OpsResult<()> {
58 if self.to.exists() {
59 let remove_filename = format!("{}.{COPY_REMOVE_FILE}", self.to.to_string_lossy());
60 let remove_filename = Path::new(&remove_filename);
61 std::fs::rename(self.to.as_path(), remove_filename)?;
62 }
63 println!("Copy: Prepare");
64 Ok(())
65 }
66
67 #[inline]
68 fn run(&self) -> OpsResult<()> {
69 std::fs::copy(self.from.as_path(), self.to.as_path())?;
70 println!("Copy: Run");
71 Ok(())
72 }
73
74 #[inline]
75 fn clean(&self) -> OpsResult<()> {
76 let remove_filename = format!("{}.{COPY_REMOVE_FILE}", self.to.to_string_lossy());
77 let remove_filename = Path::new(&remove_filename);
78 if remove_filename.exists() {
79 std::fs::remove_file(remove_filename)?;
80 }
81 println!("Copy: Clean {}", remove_filename.to_string_lossy());
82 Ok(())
83 }
84
85 #[inline]
86 fn revert_prepare(&self) -> OpsResult<()> {
87 let remove_filename = format!("{}.{COPY_REMOVE_FILE}", self.to.to_string_lossy());
88 let remove_filename = Path::new(&remove_filename);
89 if remove_filename.exists() {
90 std::fs::rename(remove_filename, self.to.as_path())?;
91 }
92 Ok(())
93 }
94
95 #[inline]
96 fn revert_run(&self) -> OpsResult<()> {
97 let remove_filename = format!("{}.{COPY_REMOVE_FILE}", self.to.to_string_lossy());
98 let remove_filename = Path::new(&remove_filename);
99 let _ = std::fs::remove_file(self.to.as_path());
101 std::fs::rename(remove_filename, self.to.as_path())?;
103 Ok(())
104 }
105
106 #[inline]
107 fn id() -> u8 {
108 COPY_FILE_ID
109 }
110
111 #[inline]
112 fn as_bytes(&self) -> &[u8] {
113 &self.bytes
114 }
115}