1use std::fs::File;
5use std::io::{BufWriter, BufReader, Write, BufRead};
6use std::path::Path;
7use chrono::{DateTime, Utc};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct PhiMetadata {
12 pub n: usize,
13 pub step: f64,
14 pub length: usize,
15 pub saved_at: DateTime<Utc>,
16}
17
18impl PhiMetadata {
19 pub fn save<P: AsRef<Path>>(&self, name: &str, base_path: P) -> std::io::Result<()> {
21 let path = base_path.as_ref().join(format!("{}.meta.txt", name));
22 let mut writer = BufWriter::new(File::create(path)?);
23 writeln!(writer, "n={}", self.n)?;
24 writeln!(writer, "step={:.6}", self.step)?;
25 writeln!(writer, "length={}", self.length)?;
26 writeln!(writer, "saved_at={}", self.saved_at.to_rfc3339())?;
27 Ok(())
28 }
29
30 pub fn load<P: AsRef<Path>>(name: &str, base_path: P) -> std::io::Result<Self> {
32 let path = base_path.as_ref().join(format!("{}.meta.txt", name));
33 let file = BufReader::new(File::open(path)?);
34
35 let mut n = 0;
36 let mut step = 0.0;
37 let mut length = 0;
38 let mut saved_at = Utc::now();
39
40 for line in file.lines() {
41 let line = line?;
42 if let Some(v) = line.strip_prefix("n=") {
43 n = v.parse().unwrap_or(0);
44 } else if let Some(v) = line.strip_prefix("step=") {
45 step = v.parse().unwrap_or(0.0);
46 } else if let Some(v) = line.strip_prefix("length=") {
47 length = v.parse().unwrap_or(0);
48 } else if let Some(v) = line.strip_prefix("saved_at=") {
49 saved_at = DateTime::parse_from_rfc3339(v)
50 .map(|dt| dt.with_timezone(&Utc))
51 .unwrap_or(Utc::now());
52 }
53 }
54
55 Ok(Self { n, step, length, saved_at })
56 }
57}