bamboo_memory/ledger_store/
paths.rs1use std::path::PathBuf;
2
3use bamboo_config::paths::bamboo_dir;
4use bamboo_domain::ledger::LedgerScope;
5
6pub const LEDGER_ROOT_DIR: &str = "ledger";
7pub const LEDGER_VERSION_DIR: &str = "v1";
8pub const SCOPES_DIR: &str = "scopes";
9pub const GLOBAL_DIR: &str = "global";
10pub const PROJECTS_DIR: &str = "projects";
11pub const RECORDS_DIR: &str = "records";
12pub const INDEXES_DIR: &str = "indexes";
13pub const VIEWS_DIR: &str = "views";
14pub const LOGS_DIR: &str = "logs";
15
16#[derive(Debug, Clone)]
27pub struct LedgerPathResolver {
28 root: PathBuf,
29}
30
31impl Default for LedgerPathResolver {
32 fn default() -> Self {
33 Self::from_data_dir(bamboo_dir())
34 }
35}
36
37impl LedgerPathResolver {
38 pub fn from_data_dir(data_dir: impl Into<PathBuf>) -> Self {
39 let root = data_dir
40 .into()
41 .join(LEDGER_ROOT_DIR)
42 .join(LEDGER_VERSION_DIR);
43 Self { root }
44 }
45
46 pub fn root(&self) -> PathBuf {
47 self.root.clone()
48 }
49
50 pub fn projects_root(&self) -> PathBuf {
51 self.root.join(SCOPES_DIR).join(PROJECTS_DIR)
52 }
53
54 pub fn scope_root(&self, scope: LedgerScope, project_key: Option<&str>) -> PathBuf {
55 let scopes = self.root.join(SCOPES_DIR);
56 match scope {
57 LedgerScope::Global => scopes.join(GLOBAL_DIR),
58 LedgerScope::Project => scopes
59 .join(PROJECTS_DIR)
60 .join(project_key.unwrap_or("unknown")),
61 }
62 }
63
64 pub fn records_dir(&self, scope: LedgerScope, project_key: Option<&str>) -> PathBuf {
65 self.scope_root(scope, project_key).join(RECORDS_DIR)
66 }
67
68 pub fn record_path(
69 &self,
70 scope: LedgerScope,
71 project_key: Option<&str>,
72 record_id: &str,
73 ) -> PathBuf {
74 self.records_dir(scope, project_key)
75 .join(format!("{}.md", record_id))
76 }
77
78 pub fn indexes_dir(&self, scope: LedgerScope, project_key: Option<&str>) -> PathBuf {
79 self.scope_root(scope, project_key).join(INDEXES_DIR)
80 }
81
82 pub fn views_dir(&self, scope: LedgerScope, project_key: Option<&str>) -> PathBuf {
83 self.scope_root(scope, project_key).join(VIEWS_DIR)
84 }
85
86 pub fn logs_dir(&self, scope: LedgerScope, project_key: Option<&str>) -> PathBuf {
87 self.scope_root(scope, project_key).join(LOGS_DIR)
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn paths_follow_v1_layout() {
97 let resolver = LedgerPathResolver::from_data_dir("/tmp/.bamboo");
98 assert_eq!(
99 resolver.record_path(LedgerScope::Global, None, "rec_1"),
100 PathBuf::from("/tmp/.bamboo/ledger/v1/scopes/global/records/rec_1.md")
101 );
102 assert_eq!(
103 resolver.record_path(LedgerScope::Project, Some("proj-1"), "rec_2"),
104 PathBuf::from("/tmp/.bamboo/ledger/v1/scopes/projects/proj-1/records/rec_2.md")
105 );
106 }
107}