shipper_core/state/store/
fs.rs1use std::path::{Path, PathBuf};
4
5use anyhow::{Context, Result};
6
7use crate::state::events::EventLog;
8use crate::state::execution_state as state;
9use crate::types::{ExecutionState, Receipt};
10
11use super::StateStore;
12
13pub struct FileStore {
17 state_dir: PathBuf,
18}
19
20impl FileStore {
21 pub fn new(state_dir: PathBuf) -> Self {
23 Self { state_dir }
24 }
25
26 pub fn state_dir(&self) -> &Path {
28 &self.state_dir
29 }
30}
31
32impl StateStore for FileStore {
33 fn save_state(&self, state: &ExecutionState) -> Result<()> {
34 state::save_state(&self.state_dir, state)
35 }
36
37 fn load_state(&self) -> Result<Option<ExecutionState>> {
38 state::load_state(&self.state_dir)
39 }
40
41 fn save_receipt(&self, receipt: &Receipt) -> Result<()> {
42 state::write_receipt(&self.state_dir, receipt)
43 }
44
45 fn load_receipt(&self) -> Result<Option<Receipt>> {
46 state::load_receipt(&self.state_dir)
47 }
48
49 fn save_events(&self, events: &EventLog) -> Result<()> {
50 let path = crate::state::events::events_path(&self.state_dir);
51 events.write_to_file(&path)
52 }
53
54 fn load_events(&self) -> Result<Option<EventLog>> {
55 let path = crate::state::events::events_path(&self.state_dir);
56 if !path.exists() {
57 return Ok(None);
58 }
59 Ok(Some(EventLog::read_from_file(&path)?))
60 }
61
62 fn clear(&self) -> Result<()> {
63 let state_path = state::state_path(&self.state_dir);
64 let receipt_path = state::receipt_path(&self.state_dir);
65 let reconciliation_path = state::reconciliation_path(&self.state_dir);
66 let events_path = crate::state::events::events_path(&self.state_dir);
67
68 if state_path.exists() {
70 std::fs::remove_file(&state_path)
71 .with_context(|| format!("failed to remove state file {}", state_path.display()))?;
72 }
73 if receipt_path.exists() {
74 std::fs::remove_file(&receipt_path).with_context(|| {
75 format!("failed to remove receipt file {}", receipt_path.display())
76 })?;
77 }
78 if reconciliation_path.exists() {
79 std::fs::remove_file(&reconciliation_path).with_context(|| {
80 format!(
81 "failed to remove reconciliation file {}",
82 reconciliation_path.display()
83 )
84 })?;
85 }
86 if events_path.exists() {
87 std::fs::remove_file(&events_path).with_context(|| {
88 format!("failed to remove events file {}", events_path.display())
89 })?;
90 }
91
92 Ok(())
93 }
94}