Skip to main content

void_core/index/
io.rs

1//! Read/write operations for the workspace index with encryption.
2
3use 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
22/// Writes the encrypted workspace index to disk.
23pub 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    // Atomic write via temp file + rename
38    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
45/// Writes a WorkspaceIndex directly to disk.
46pub 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    // Atomic write via temp file + rename
59    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
66/// Reads the encrypted workspace index from disk.
67pub 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}