1use std::time::{SystemTime, UNIX_EPOCH};
2
3use anyhow::Result;
4use serde::{Deserialize, Serialize};
5
6use super::{AtomState, LoreAtom, Workspace};
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
9pub struct AcceptedLoreRecord {
10 pub atom: LoreAtom,
11 pub accepted_unix_seconds: u64,
12 pub source_commit: Option<String>,
13}
14
15impl AcceptedLoreRecord {
16 pub fn new(atom: LoreAtom, source_commit: Option<String>) -> Self {
17 Self {
18 atom,
19 accepted_unix_seconds: now_unix_seconds(),
20 source_commit,
21 }
22 }
23}
24
25impl Workspace {
26 pub fn write_accepted_atom(&self, atom: &LoreAtom, source_commit: Option<&str>) -> Result<()> {
27 let mut accepted_atom = atom.clone();
28 accepted_atom.state = AtomState::Accepted;
29
30 let record = AcceptedLoreRecord::new(
31 accepted_atom.clone(),
32 source_commit.map(str::to_owned),
33 );
34 let path = self
35 .refs_lore_accepted_dir()
36 .join(format!("{}.json", accepted_atom.id));
37
38 self.write_json(&path, &record)
39 }
40
41 pub fn load_accepted_atoms(&self) -> Result<Vec<AcceptedLoreRecord>> {
42 self.ensure_layout()?;
43
44 let mut records = Vec::new();
45 for entry in std::fs::read_dir(self.refs_lore_accepted_dir())? {
46 let entry = entry?;
47 let path = entry.path();
48 if path.extension().and_then(|value| value.to_str()) != Some("json") {
49 continue;
50 }
51
52 let record: AcceptedLoreRecord = self.read_json(&path)?;
53 records.push(record);
54 }
55
56 records.sort_by(|left, right| {
57 left.accepted_unix_seconds
58 .cmp(&right.accepted_unix_seconds)
59 .then(left.atom.id.cmp(&right.atom.id))
60 });
61 Ok(records)
62 }
63}
64
65fn now_unix_seconds() -> u64 {
66 SystemTime::now()
67 .duration_since(UNIX_EPOCH)
68 .map(|duration| duration.as_secs())
69 .unwrap_or(0)
70}