oxihuman_core/
temp_file_manager.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct TempFile {
10 pub path: String,
11 pub size_bytes: u64,
12 pub deleted: bool,
13}
14
15impl TempFile {
16 pub fn new(path: &str) -> Self {
17 TempFile {
18 path: path.to_string(),
19 size_bytes: 0,
20 deleted: false,
21 }
22 }
23
24 pub fn write_bytes(&mut self, bytes: u64) {
25 self.size_bytes += bytes;
26 }
27
28 pub fn delete(&mut self) {
29 self.deleted = true;
30 self.size_bytes = 0;
31 }
32
33 pub fn is_alive(&self) -> bool {
34 !self.deleted
35 }
36}
37
38pub struct TempFileManager {
40 prefix: String,
41 counter: u64,
42 files: Vec<TempFile>,
43}
44
45impl TempFileManager {
46 pub fn new(prefix: &str) -> Self {
47 TempFileManager {
48 prefix: prefix.to_string(),
49 counter: 0,
50 files: Vec::new(),
51 }
52 }
53
54 pub fn create(&mut self) -> &mut TempFile {
55 let path = format!("{}{}.tmp", self.prefix, self.counter);
56 self.counter += 1;
57 self.files.push(TempFile::new(&path));
58 let len = self.files.len();
59 &mut self.files[len - 1]
60 }
61
62 pub fn cleanup_all(&mut self) {
63 for f in &mut self.files {
64 f.delete();
65 }
66 }
67
68 pub fn alive_count(&self) -> usize {
69 self.files.iter().filter(|f| f.is_alive()).count()
70 }
71
72 pub fn total_size(&self) -> u64 {
73 self.files.iter().map(|f| f.size_bytes).sum()
74 }
75
76 pub fn all_files(&self) -> &[TempFile] {
77 &self.files
78 }
79}
80
81impl Default for TempFileManager {
82 fn default() -> Self {
83 Self::new("/tmp/oxihuman_")
84 }
85}
86
87pub fn new_temp_manager() -> TempFileManager {
89 TempFileManager::default()
90}
91
92pub fn create_n(mgr: &mut TempFileManager, n: usize) -> Vec<String> {
94 (0..n).map(|_| mgr.create().path.clone()).collect()
95}
96
97pub fn alive_total_bytes(mgr: &TempFileManager) -> u64 {
99 mgr.files
100 .iter()
101 .filter(|f| f.is_alive())
102 .map(|f| f.size_bytes)
103 .sum()
104}
105
106pub fn delete_by_path(mgr: &mut TempFileManager, path: &str) {
108 if let Some(f) = mgr.files.iter_mut().find(|f| f.path == path) {
109 f.delete();
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_create_temp_file() {
119 let mut m = new_temp_manager();
120 let f = m.create();
121 assert!(f.is_alive());
122 }
123
124 #[test]
125 fn test_alive_count() {
126 let mut m = new_temp_manager();
127 create_n(&mut m, 3);
128 assert_eq!(m.alive_count(), 3);
129 }
130
131 #[test]
132 fn test_cleanup_all() {
133 let mut m = new_temp_manager();
134 create_n(&mut m, 2);
135 m.cleanup_all();
136 assert_eq!(m.alive_count(), 0);
137 }
138
139 #[test]
140 fn test_write_bytes() {
141 let mut m = new_temp_manager();
142 m.create().write_bytes(512);
143 assert_eq!(m.total_size(), 512);
144 }
145
146 #[test]
147 fn test_alive_total_bytes() {
148 let mut m = new_temp_manager();
149 m.create().write_bytes(100);
150 assert_eq!(alive_total_bytes(&m), 100);
151 }
152
153 #[test]
154 fn test_delete_by_path() {
155 let mut m = new_temp_manager();
156 let paths = create_n(&mut m, 2);
157 delete_by_path(&mut m, &paths[0]);
158 assert_eq!(m.alive_count(), 1);
159 }
160
161 #[test]
162 fn test_create_n_paths_unique() {
163 let mut m = new_temp_manager();
164 let paths = create_n(&mut m, 3);
165 let unique: std::collections::HashSet<_> = paths.iter().collect();
166 assert_eq!(unique.len(), 3);
167 }
168
169 #[test]
170 fn test_total_size_after_delete() {
171 let mut m = new_temp_manager();
172 m.create().write_bytes(200);
173 m.cleanup_all();
174 assert_eq!(m.total_size(), 0);
175 }
176
177 #[test]
178 fn test_all_files_accessible() {
179 let mut m = new_temp_manager();
180 create_n(&mut m, 2);
181 assert_eq!(m.all_files().len(), 2);
182 }
183
184 #[test]
185 fn test_default_prefix() {
186 let m = TempFileManager::default();
187 assert!(m.prefix.contains("oxihuman"));
188 }
189}