lgp/core/
characteristics.rs1use std::{
2 error::Error,
3 fs::{read_to_string, OpenOptions},
4 io::Write,
5 path::{Path, PathBuf},
6};
7
8use serde::{de::DeserializeOwned, Serialize};
9use tracing;
10
11use crate::utils::misc::create_path;
12
13pub trait Load
14where
15 Self: Sized + DeserializeOwned,
16{
17 fn load(path: impl Into<PathBuf>) -> Self {
18 let contents = read_to_string(path.into()).unwrap();
19 let deserialized: Self = serde_json::from_str(&contents).unwrap();
20
21 deserialized
22 }
23}
24
25pub trait Save
26where
27 Self: Serialize,
28{
29 fn save(&self, path: &str) -> Result<String, Box<dyn Error>> {
30 create_path(path, true)?;
31
32 tracing::trace!(path = path, "Attempting JSON serialization");
33 let serialized = match serde_json::to_string_pretty(&self) {
34 Ok(s) => s,
35 Err(e) => {
36 tracing::error!(path = path, error = %e, "JSON serialization failed");
37 return Err(e.into());
38 }
39 };
40 tracing::trace!(
41 path = path,
42 bytes = serialized.len(),
43 "Serialization successful"
44 );
45
46 let mut file = OpenOptions::new()
47 .write(true)
48 .create(true)
49 .truncate(true)
50 .open(Path::new(path))?;
51
52 file.write_all(serialized.as_bytes())?;
53
54 Ok(serialized)
55 }
56}
57
58pub trait Reproduce: Load + Save {}
59
60impl<T> Load for T where T: Sized + DeserializeOwned {}
61impl<T> Save for T where T: Serialize {}
62impl<T> Reproduce for T where T: Load + Save {}