1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use context::Context;
use holochain_core_types::error::HolochainError;
use state::State;
use std::{
fs::{File, OpenOptions},
io::{Read, Write},
sync::Arc,
};
pub trait Persister: Send {
fn save(&mut self, state: State) -> Result<(), HolochainError>;
fn load(&self, context: Arc<Context>) -> Result<Option<State>, HolochainError>;
}
#[derive(Default, Clone, PartialEq)]
pub struct SimplePersister {
state: Option<State>,
file_path: String,
}
impl Persister for SimplePersister {
fn save(&mut self, state: State) -> Result<(), HolochainError> {
let mut f = OpenOptions::new()
.write(true)
.create(true)
.open(self.file_path.clone())?;
let json = State::serialize_state(state)?;
Ok(f.write_all(json.as_bytes())?)
}
fn load(&self, context: Arc<Context>) -> Result<Option<State>, HolochainError> {
let mut f = File::open(self.file_path.clone())?;
let mut json = String::new();
f.read_to_string(&mut json)?;
let state = State::deserialize_state(context, json)?;
Ok(Some(state))
}
}
impl SimplePersister {
pub fn new(file: String) -> Self {
SimplePersister {
state: None,
file_path: file,
}
}
}
#[cfg(test)]
mod tests {
extern crate tempfile;
use self::tempfile::tempdir;
use super::*;
use instance::tests::test_context_with_agent_state;
use test_utils::create_test_context;
#[test]
fn persistance_round_trip() {
let dir = tempdir().unwrap();
let temp_path = dir.path().join("test");
let tempfile = temp_path.to_str().unwrap();
let context = test_context_with_agent_state();
File::create(temp_path.clone()).unwrap();
let mut persistance = SimplePersister::new(tempfile.to_string());
let state = context.state().unwrap().clone();
persistance.save(state.clone()).unwrap();
let state_from_file = persistance.load(context).unwrap().unwrap();
assert_eq!(state, state_from_file)
}
}