1
2use std::fs::*;
3use std::io::{self, Read, Write};
4use std::path::{Path, PathBuf};
5use std::fs;
6use std::env;
7use log::error;
8
9const ROOT_DIR: &str = "Alice-Database-Data";
10const ADB_DATA_DIR: &str = "ADB_Data";
11const LOG_ENGINE_DIR: &str = "log_engine";
12
13#[derive(Debug, Clone)]
14pub struct Document {
15 pub name: String,
16 pub path: PathBuf,
17 pub data: String,
18}
19
20#[derive(Debug, Clone)]
21pub struct Collection {
22 pub name: String,
23 pub documents: Vec<Document>,
24}
25
26impl Collection {
27 pub fn get_document(&self, name: &str) -> Option<&Document> {
29 self.documents.iter().find(|doc| doc.name == name)
30 }
31
32 pub fn get_document_mut(&mut self, name: &str) -> Option<&mut Document> {
41 self.documents.iter_mut().find(|doc| doc.name == name)
42 }
43
44 pub fn add_document(&mut self, name: &str, content: &str) -> io::Result<()> {
46 let collection_path = Path::new(&self.path()).join(&self.name);
47 fs::create_dir_all(&collection_path)?;
48
49 let doc_path = collection_path.join(&name.clone()); let mut file = fs::File::create(&doc_path)?;
52 file.write_all(content.as_bytes())?;
53
54 let new_document = Document {
56 name: name.to_string(),
57 path: doc_path.clone(),
58 data: content.to_string(),
59 };
60 self.documents.push(new_document);
61 Ok(())
62 }
63
64 pub fn delete_document(&mut self, name: &str) -> io::Result<()> {
66 if let Some(doc) = self.documents.iter().find(|doc| doc.name == name) {
67 fs::remove_file(&doc.path)?;
68 self.documents.retain(|doc| doc.name != name);
69 Ok(())
70 } else {
71 Err(io::Error::new(io::ErrorKind::NotFound, "Document not found"))
72 }
73 }
74
75 fn path(&self) -> PathBuf {
76 let home_dir = env::home_dir().expect("Failed to get home directory");
77 home_dir.join(ROOT_DIR).join(ADB_DATA_DIR).join(LOG_ENGINE_DIR)
78 }
79}
80
81#[derive(Debug, Clone)]
82pub struct LOGEngine {
83 pub collections: Vec<Collection>,
84}
85impl LOGEngine {
86 pub fn new(root: &Path, ) -> Self {
94 let collections = get_exists_collections(root);
95 LOGEngine { collections }
96 }
97
98
99 pub fn get_collection_mut(&mut self, name: &str) -> Option<&mut Collection> {
107 self.collections.iter_mut().find(|col| col.name == name)
108 }
109
110 pub fn add_collection(&mut self, name: &str) -> Option<&mut Collection> {
118 let collection_path = Path::new(&self.root_path()).join(name);
119 fs::create_dir_all(&collection_path).ok()?; let new_collection = Collection {
122 name: name.to_string(),
123 documents: vec![],
124 };
125
126 self.collections.push(new_collection);
127 self.collections.last_mut() }
129
130 pub fn get_collection(&self, name: &str) -> Option<&Collection> {
138 self.collections.iter().find(|col| col.name == name)
139 }
140
141 pub fn get_document(&self, collection_name: &str, document_name: &str) -> Option<&Document> {
150 self.get_collection(collection_name)?.get_document(document_name)
151 }
152
153 fn root_path(&self) -> PathBuf {
154 let home_dir = env::home_dir().expect("Failed to get home directory");
155 home_dir.join(ROOT_DIR).join(ADB_DATA_DIR).join(LOG_ENGINE_DIR)
156 }
157}
158
159
160fn get_documents_in_collection(path: &Path) -> Vec<Document> {
162 let entries = fs::read_dir(path).unwrap();
163 let mut documents: Vec<Document> = vec![];
164
165 for entry in entries {
166 let entry = entry.unwrap();
167 let entry_path = entry.path();
168 if entry_path.is_file() {
169 let name = entry_path.file_name().unwrap().to_string_lossy().into_owned();
170 let data = read_file_data(&entry_path).unwrap_or_default();
171 let document = Document {
172 name,
173 path: entry_path.clone(),
174 data,
175 };
176 documents.push(document);
177 }
178 }
179 documents
180}
181
182fn read_file_data(path: &Path) -> io::Result<String> {
183 let mut file = fs::File::open(path)?;
184 let mut contents = String::new();
185 file.read_to_string(&mut contents)?;
186 Ok(contents)
187}
188
189fn get_exists_collections(path: &Path) -> Vec<Collection> {
190 let mut collections: Vec<Collection> = vec![];
191
192 if path.exists() && path.is_dir() {
193 let entries = fs::read_dir(path).unwrap();
194
195 for entry in entries {
196 let entry = entry.unwrap();
197 let entry_path = entry.path();
198
199 if entry_path.is_dir() {
200 let documents = get_documents_in_collection(&entry_path);
201 let collection_name = entry_path.file_name().unwrap().to_string_lossy().into_owned();
202 let collection = Collection {
203 name: collection_name,
204 documents,
205 };
206 collections.push(collection);
207 }
208 }
209 } else {
210 error!("The specified path does not exist or is not a directory: {:?}", path);
211 }
212
213 collections
214}