atomic_ops/process/
mod.rs1pub mod constants;
2pub mod file;
3
4use crate::error::{OpsError, OpsResult};
5use std::cell::RefCell;
6
7#[derive(Clone, Copy, Debug)]
8pub enum ProcStatus {
9 INIT,
10 PREPARED,
11 RAN,
12 CLEAN,
13 REVERTED,
14}
15
16impl From<ProcStatus> for u8 {
17 fn from(value: ProcStatus) -> Self {
18 match value {
19 ProcStatus::INIT => 0,
20 ProcStatus::PREPARED => 1,
21 ProcStatus::RAN => 2,
22 ProcStatus::CLEAN => 3,
23 ProcStatus::REVERTED => 4,
24 }
25 }
26}
27
28impl TryFrom<u8> for ProcStatus {
29 type Error = OpsError;
30
31 fn try_from(value: u8) -> Result<Self, Self::Error> {
32 match value {
33 0 => Ok(ProcStatus::INIT),
34 1 => Ok(ProcStatus::PREPARED),
35 2 => Ok(ProcStatus::RAN),
36 3 => Ok(ProcStatus::CLEAN),
37 4 => Ok(ProcStatus::REVERTED),
38 _ => Err(OpsError::SerializeFailed),
39 }
40 }
41}
42
43pub trait Process {
44 fn prepare(&self) -> OpsResult<()>;
45 fn run(&self) -> OpsResult<()>;
46 fn clean(&self) -> OpsResult<()>;
47
48 fn revert_prepare(&self) -> OpsResult<()>;
49 fn revert_run(&self) -> OpsResult<()>;
50
51 fn as_bytes(&self) -> &[u8];
52
53 fn id() -> u8
54 where
55 Self: Sized;
56}
57
58pub struct BoxedProc {
59 id: u8,
60 offset: usize,
61 status: RefCell<ProcStatus>,
62 process: Box<dyn Process>,
63}
64
65pub const STATUS_SHIFT: usize = 5;
66pub const BOXED_PROC_SIZE: usize = 6; impl BoxedProc {
68 pub fn new(id: u8, process: Box<dyn Process>) -> Self {
69 Self {
70 id,
71 offset: 0,
72 status: RefCell::new(ProcStatus::INIT),
73 process,
74 }
75 }
76
77 pub fn new_with_offset(
78 id: u8,
79 process: Box<dyn Process>,
80 status: ProcStatus,
81 offset: usize,
82 ) -> Self {
83 Self {
84 id,
85 offset,
86 status: RefCell::new(status),
87 process,
88 }
89 }
90
91 #[inline]
92 pub fn prepare(&self) -> OpsResult<()> {
93 println!("Prepare {}", self.id);
94 let mut borrow = self
95 .status
96 .try_borrow_mut()
97 .map_err(|_| OpsError::BorrowingStatusFailed)?;
98 self.process.prepare()?;
99 *borrow = ProcStatus::PREPARED;
100 Ok(())
101 }
102
103 #[inline]
104 pub fn run(&self) -> OpsResult<()> {
105 println!("Run {}", self.id);
106 let mut borrow = self
107 .status
108 .try_borrow_mut()
109 .map_err(|_| OpsError::BorrowingStatusFailed)?;
110 self.process.run()?;
111 *borrow = ProcStatus::RAN;
112 Ok(())
113 }
114
115 #[inline]
116 pub fn clean(&self) -> OpsResult<()> {
117 println!("Clean {}", self.id);
118 let mut borrow = self
119 .status
120 .try_borrow_mut()
121 .map_err(|_| OpsError::BorrowingStatusFailed)?;
122 self.process.clean()?;
123 *borrow = ProcStatus::CLEAN;
124 Ok(())
125 }
126
127 #[inline]
128 pub fn revert_prepare(&self) -> OpsResult<()> {
129 println!("Revert PREPARE {}", self.id);
130 self.process.revert_prepare()
131 }
132
133 #[inline]
134 pub fn revert_run(&self) -> OpsResult<()> {
135 println!("Revert RUN {}", self.id);
136 self.process.revert_run()
137 }
138
139 #[inline]
140 pub fn status(&self) -> ProcStatus {
141 *self.status.borrow()
142 }
143
144 #[inline]
145 pub fn offcet(&self) -> usize {
146 self.offset
147 }
148
149 #[inline]
150 pub fn id(&self) -> u8 {
151 self.id
152 }
153
154 #[inline]
155 pub fn set_offset(&mut self, offset: usize) {
156 self.offset = offset;
157 }
158
159 #[inline]
160 pub fn encode(&self) -> Vec<u8> {
161 let process_bytes = self.process.as_bytes();
162 let length = process_bytes.len();
163 let status: u8 = self.status().into();
164 let mut bytes = Vec::with_capacity(length);
165
166 bytes.extend_from_slice((length as u32).to_le_bytes().as_slice());
168 bytes.extend_from_slice(&[self.id]);
169 bytes.extend_from_slice(&[status]);
170 bytes.extend_from_slice(process_bytes);
171 bytes
172 }
173
174 #[inline]
175 pub fn print(&self) {
176 println!("BoxedProc: {}, {:?}", self.id, self.status)
177 }
178}