rustodo/storage/
memory.rs1use anyhow::Result;
4use std::cell::RefCell;
5
6use super::Storage;
7use crate::models::Task;
8
9#[derive(Default)]
23pub struct InMemoryStorage {
24 tasks: RefCell<Vec<Task>>,
25}
26
27#[allow(dead_code)]
28impl InMemoryStorage {
29 pub fn with_tasks(tasks: Vec<Task>) -> Self {
33 Self {
34 tasks: RefCell::new(tasks),
35 }
36 }
37
38 pub fn len(&self) -> usize {
40 self.tasks.borrow().len()
41 }
42
43 pub fn is_empty(&self) -> bool {
45 self.tasks.borrow().is_empty()
46 }
47}
48
49impl Storage for InMemoryStorage {
50 fn load(&self) -> Result<Vec<Task>> {
51 Ok(self.tasks.borrow().clone())
52 }
53
54 fn save(&self, tasks: &[Task]) -> Result<()> {
55 *self.tasks.borrow_mut() = tasks.to_vec();
56 Ok(())
57 }
58
59 fn location(&self) -> String {
60 "memory".to_string()
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::models::Priority;
68
69 #[test]
70 fn test_memory_storage_starts_empty() {
71 let storage = InMemoryStorage::default();
72
73 assert_eq!(storage.len(), 0);
74 assert!(storage.is_empty());
75 assert_eq!(storage.load().unwrap().len(), 0);
76 }
77
78 #[test]
79 fn test_memory_storage_save_and_load() {
80 let storage = InMemoryStorage::default();
81
82 let tasks = vec![
84 Task::new(
85 "Task 1".to_string(),
86 Priority::High,
87 vec![],
88 None,
89 None,
90 None,
91 ),
92 Task::new(
93 "Task 2".to_string(),
94 Priority::Low,
95 vec![],
96 None,
97 None,
98 None,
99 ),
100 ];
101 storage.save(&tasks).unwrap();
102
103 let loaded = storage.load().unwrap();
105 assert_eq!(loaded.len(), 2);
106 assert_eq!(loaded[0].text, "Task 1");
107 assert_eq!(loaded[1].text, "Task 2");
108 }
109
110 #[test]
111 fn test_memory_storage_with_tasks() {
112 let tasks = vec![Task::new(
113 "Existing".to_string(),
114 Priority::Medium,
115 vec![],
116 None,
117 None,
118 None,
119 )];
120
121 let storage = InMemoryStorage::with_tasks(tasks);
122
123 assert_eq!(storage.len(), 1);
124 assert!(!storage.is_empty());
125
126 let loaded = storage.load().unwrap();
127 assert_eq!(loaded[0].text, "Existing");
128 }
129
130 #[test]
131 fn test_memory_storage_overwrite() {
132 let storage = InMemoryStorage::default();
133
134 let tasks1 = vec![Task::new(
136 "Task 1".to_string(),
137 Priority::Medium,
138 vec![],
139 None,
140 None,
141 None,
142 )];
143 storage.save(&tasks1).unwrap();
144 assert_eq!(storage.len(), 1);
145
146 let tasks2 = vec![
148 Task::new(
149 "Task 2".to_string(),
150 Priority::High,
151 vec![],
152 None,
153 None,
154 None,
155 ),
156 Task::new(
157 "Task 3".to_string(),
158 Priority::Low,
159 vec![],
160 None,
161 None,
162 None,
163 ),
164 ];
165 storage.save(&tasks2).unwrap();
166
167 assert_eq!(storage.len(), 2);
169 let loaded = storage.load().unwrap();
170 assert_eq!(loaded[0].text, "Task 2");
171 assert_eq!(loaded[1].text, "Task 3");
172 }
173
174 #[test]
175 fn test_memory_storage_location() {
176 let storage = InMemoryStorage::default();
177 assert_eq!(storage.location(), "memory");
178 }
179}