1use std::path::PathBuf;
23
24pub struct StorePaths {
29 root: PathBuf,
30}
31
32impl StorePaths {
33 pub fn new(data_dir: impl Into<PathBuf>) -> Self {
35 Self {
36 root: data_dir.into(),
37 }
38 }
39
40 pub fn docs_root(&self) -> PathBuf {
42 self.root.join("docs")
43 }
44
45 pub fn doc_dir(&self, doc_id: &str) -> PathBuf {
49 self.docs_root().join(doc_id)
50 }
51
52 pub fn objects_dir(&self, doc_id: &str) -> PathBuf {
56 self.doc_dir(doc_id).join("objects")
57 }
58
59 pub fn versions_file(&self, doc_id: &str) -> PathBuf {
63 self.doc_dir(doc_id).join("versions.jsonl")
64 }
65
66 pub fn session_dir(&self, doc_id: &str) -> PathBuf {
70 self.doc_dir(doc_id).join("session")
71 }
72
73 pub fn meta_file(&self, doc_id: &str) -> PathBuf {
77 self.doc_dir(doc_id).join("meta.json")
78 }
79
80 pub fn runs_file(&self, doc_id: &str) -> PathBuf {
82 self.doc_dir(doc_id).join("runs.jsonl")
83 }
84
85 pub fn previews_file(&self, doc_id: &str) -> PathBuf {
87 self.doc_dir(doc_id).join("previews.jsonl")
88 }
89
90 pub fn scratch_dir(&self, doc_id: &str) -> PathBuf {
92 self.doc_dir(doc_id).join("scratch")
93 }
94
95 pub fn scratch_index(&self, doc_id: &str) -> PathBuf {
97 self.scratch_dir(doc_id).join("index.jsonl")
98 }
99
100 pub fn workspace_dir(&self, doc_id: &str) -> PathBuf {
103 self.doc_dir(doc_id).join("workspace")
104 }
105
106 pub fn workspace_renders_dir(&self, doc_id: &str) -> PathBuf {
112 self.workspace_dir(doc_id).join("renders")
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119
120 fn paths() -> StorePaths {
121 StorePaths::new("/data")
122 }
123
124 #[test]
125 fn docs_root() {
126 assert_eq!(paths().docs_root(), PathBuf::from("/data/docs"));
127 }
128
129 #[test]
130 fn doc_dir() {
131 assert_eq!(paths().doc_dir("doc1"), PathBuf::from("/data/docs/doc1"));
132 }
133
134 #[test]
135 fn objects_dir() {
136 assert_eq!(
137 paths().objects_dir("doc1"),
138 PathBuf::from("/data/docs/doc1/objects")
139 );
140 }
141
142 #[test]
143 fn versions_file() {
144 assert_eq!(
145 paths().versions_file("doc1"),
146 PathBuf::from("/data/docs/doc1/versions.jsonl")
147 );
148 }
149
150 #[test]
151 fn session_dir() {
152 assert_eq!(
153 paths().session_dir("doc1"),
154 PathBuf::from("/data/docs/doc1/session")
155 );
156 }
157
158 #[test]
159 fn different_doc_ids_produce_different_paths() {
160 let p = paths();
161 assert_ne!(p.doc_dir("alpha"), p.doc_dir("beta"));
162 }
163
164 #[test]
165 fn meta_file() {
166 assert_eq!(
167 paths().meta_file("doc1"),
168 PathBuf::from("/data/docs/doc1/meta.json")
169 );
170 }
171
172 #[test]
173 fn runs_file() {
174 assert_eq!(
175 paths().runs_file("doc1"),
176 PathBuf::from("/data/docs/doc1/runs.jsonl")
177 );
178 }
179
180 #[test]
181 fn previews_file() {
182 assert_eq!(
183 paths().previews_file("doc1"),
184 PathBuf::from("/data/docs/doc1/previews.jsonl")
185 );
186 }
187
188 #[test]
189 fn scratch_dir() {
190 assert_eq!(
191 paths().scratch_dir("doc1"),
192 PathBuf::from("/data/docs/doc1/scratch")
193 );
194 }
195
196 #[test]
197 fn scratch_index() {
198 assert_eq!(
199 paths().scratch_index("doc1"),
200 PathBuf::from("/data/docs/doc1/scratch/index.jsonl")
201 );
202 }
203
204 #[test]
205 fn workspace_dir() {
206 assert_eq!(
207 paths().workspace_dir("doc1"),
208 PathBuf::from("/data/docs/doc1/workspace")
209 );
210 }
211
212 #[test]
213 fn workspace_renders_dir() {
214 assert_eq!(
215 paths().workspace_renders_dir("doc1"),
216 PathBuf::from("/data/docs/doc1/workspace/renders")
217 );
218 }
219}