task_tracker_cli/storage/
file_storage.rs

1/// File-based storage implementation
2
3use std::fs;
4use std::path::Path;
5use crate::storage::Storage;
6use tracing::{debug, error, warn};
7
8/// File storage for persisting task data
9pub struct FileStorage {
10    path: String,
11}
12
13impl FileStorage {
14    /// Creates a new FileStorage instance
15    pub fn new(path: Option<String>) -> Self {
16        let storage_path = path.unwrap_or_else(|| {
17            format!("temp/{}", chrono::Local::now().timestamp_millis())
18        });
19        debug!("Initializing FileStorage with path: {}", storage_path);
20        FileStorage { path: storage_path }
21    }
22
23    pub fn path(&self) -> &str {
24        &self.path
25    }
26}
27
28impl Storage for FileStorage {
29    fn save(&self, data: String) -> Result<(), String> {
30        // Create parent directories if they don't exist
31        match fs::exists(&self.path) {
32            Ok(exist) => {
33                if !exist {
34                    let path = Path::new(&self.path);
35                    match fs::create_dir_all(path.parent().unwrap()) {
36                        Ok(_) => {
37                            debug!("Directory created: {}", self.path);
38                        }
39                        Err(e) => {
40                            error!("Failed to create directory: {}", e);
41                            return Err(format!("Failed to create directory: {}", e));
42                        }
43                    }
44                }
45            }
46            Err(e) => {
47                error!("File system error: {}", e);
48                return Err(format!("File system error: {}", e));
49            }
50        }
51
52        // Write data to file
53        match fs::write(&self.path, data) {
54            Ok(_) => {
55                debug!("Data saved successfully to: {}", self.path);
56                Ok(())
57            }
58            Err(e) => {
59                error!("Failed to save data: {}", e);
60                Err(format!("Failed to save data: {}", e))
61            }
62        }
63    }
64
65    fn load(&self) -> Result<String, String> {
66        match fs::read_to_string(&self.path) {
67            Ok(content) => {
68                debug!("Data loaded from: {}", self.path);
69                Ok(content)
70            }
71            Err(e) => {
72                warn!("Failed to read file {}: {}", self.path, e);
73                Err(format!("Failed to read file: {}", e))
74            }
75        }
76    }
77}