1use std::fs;
4use std::path::{Path, PathBuf};
5
6use void_crypto::EncryptedIndex;
7
8use void_crypto::CommitCid;
9
10use crate::crypto::SecretKey;
11use crate::{Result, VoidError};
12
13use super::types::IndexEntry;
14use super::workspace::WorkspaceIndex;
15
16const INDEX_FILENAME: &str = "index.bin";
17
18fn index_path(void_dir: impl AsRef<Path>) -> PathBuf {
19 void_dir.as_ref().join("index").join(INDEX_FILENAME)
20}
21
22pub fn write_index(
24 void_dir: impl AsRef<Path>,
25 key: &SecretKey,
26 commit_cid: Option<CommitCid>,
27 entries: Vec<IndexEntry>,
28) -> Result<()> {
29 let void_dir = void_dir.as_ref();
30 let index = WorkspaceIndex::new(commit_cid, entries);
31 let bytes = crate::support::cbor_to_vec(&index)?;
32 let blob = EncryptedIndex::encrypt(key.as_bytes(), &bytes)?;
33
34 let index_dir = void_dir.join("index");
35 fs::create_dir_all(&index_dir)?;
36
37 let index_file = index_path(void_dir);
39 let temp_path = index_file.with_extension("tmp");
40 fs::write(&temp_path, blob.as_bytes())?;
41 fs::rename(&temp_path, &index_file)?;
42 Ok(())
43}
44
45pub fn write_workspace_index(
47 void_dir: impl AsRef<Path>,
48 key: &SecretKey,
49 index: &WorkspaceIndex,
50) -> Result<()> {
51 let void_dir = void_dir.as_ref();
52 let bytes = crate::support::cbor_to_vec(index)?;
53 let blob = EncryptedIndex::encrypt(key.as_bytes(), &bytes)?;
54
55 let index_dir = void_dir.join("index");
56 fs::create_dir_all(&index_dir)?;
57
58 let index_file = index_path(void_dir);
60 let temp_path = index_file.with_extension("tmp");
61 fs::write(&temp_path, blob.as_bytes())?;
62 fs::rename(&temp_path, &index_file)?;
63 Ok(())
64}
65
66pub fn read_index(void_dir: impl AsRef<Path>, key: &SecretKey) -> Result<WorkspaceIndex> {
68 let raw = fs::read(index_path(void_dir)).map_err(|_| VoidError::NotFound("index".into()))?;
69 let blob = EncryptedIndex::from_bytes(raw);
70 Ok(blob.decrypt_and_parse(key.as_bytes())?)
71}