Skip to main content

cc_sync_session/
mock.rs

1use std::collections::HashMap;
2use std::path::{Path, PathBuf};
3use std::sync::{Arc, Mutex};
4use std::time::SystemTime;
5
6use crate::filesystem::{EntryMetadata, FileSystem, FileSystemError, Result};
7
8#[derive(Debug, Clone)]
9struct MockFile {
10    content: Vec<u8>,
11    modified: SystemTime,
12}
13
14#[derive(Debug, Clone)]
15pub struct MockFileSystem {
16    files: Arc<Mutex<HashMap<PathBuf, MockFile>>>,
17    directories: Arc<Mutex<Vec<PathBuf>>>,
18}
19
20impl MockFileSystem {
21    pub fn new() -> Self {
22        Self {
23            files: Arc::new(Mutex::new(HashMap::new())),
24            directories: Arc::new(Mutex::new(Vec::new())),
25        }
26    }
27    
28    pub fn add_file(&self, path: impl Into<PathBuf>, content: Vec<u8>, modified: SystemTime) {
29        let path = path.into();
30        let mut files = self.files.lock().unwrap();
31        files.insert(path, MockFile { content, modified });
32    }
33    
34    pub fn add_directory(&self, path: impl Into<PathBuf>) {
35        let path = path.into();
36        let mut directories = self.directories.lock().unwrap();
37        if !directories.contains(&path) {
38            directories.push(path);
39        }
40    }
41    
42    pub fn get_file_content(&self, path: &Path) -> Option<Vec<u8>> {
43        let files = self.files.lock().unwrap();
44        files.get(path).map(|f| f.content.clone())
45    }
46    
47    pub fn list_all_files(&self) -> Vec<PathBuf> {
48        let files = self.files.lock().unwrap();
49        files.keys().cloned().collect()
50    }
51}
52
53impl FileSystem for MockFileSystem {
54    fn list_directory(&self, path: &Path) -> Result<Vec<EntryMetadata>> {
55        let files = self.files.lock().unwrap();
56        let directories = self.directories.lock().unwrap();
57        
58        let mut results = Vec::new();
59        
60        // Check if the directory exists
61        if path != Path::new("") && !directories.contains(&path.to_path_buf()) {
62            return Err(FileSystemError::NotFound(path.to_path_buf()));
63        }
64        
65        // List files in the directory
66        for (file_path, file) in files.iter() {
67            if let Some(parent) = file_path.parent() {
68                if parent == path {
69                    results.push(EntryMetadata {
70                        path: file_path.clone(),
71                        modified: file.modified,
72                        is_directory: false,
73                    });
74                }
75            }
76        }
77        
78        // List subdirectories
79        for dir_path in directories.iter() {
80            if let Some(parent) = dir_path.parent() {
81                if parent == path && dir_path != path {
82                    results.push(EntryMetadata {
83                        path: dir_path.clone(),
84                        modified: SystemTime::now(),
85                        is_directory: true,
86                    });
87                }
88            }
89        }
90        
91        Ok(results)
92    }
93    
94    fn get_metadata(&self, path: &Path) -> Result<EntryMetadata> {
95        let files = self.files.lock().unwrap();
96        let directories = self.directories.lock().unwrap();
97        
98        if let Some(file) = files.get(path) {
99            Ok(EntryMetadata {
100                path: path.to_path_buf(),
101                modified: file.modified,
102                is_directory: false,
103            })
104        } else if directories.contains(&path.to_path_buf()) {
105            Ok(EntryMetadata {
106                path: path.to_path_buf(),
107                modified: SystemTime::now(),
108                is_directory: true,
109            })
110        } else {
111            Err(FileSystemError::NotFound(path.to_path_buf()))
112        }
113    }
114    
115    fn copy_file(&self, from: &Path, to: &Path) -> Result<()> {
116        // Ensure parent directory exists
117        if let Some(parent) = to.parent() {
118            self.create_directory(parent)?;
119        }
120        
121        let mut files = self.files.lock().unwrap();
122        
123        let source_file = files.get(from)
124            .ok_or_else(|| FileSystemError::NotFound(from.to_path_buf()))?
125            .clone();
126        
127        files.insert(to.to_path_buf(), source_file);
128        Ok(())
129    }
130    
131    fn create_directory(&self, path: &Path) -> Result<()> {
132        // Create parent directories recursively
133        if let Some(parent) = path.parent() {
134            if parent != Path::new("") && parent != Path::new("/") {
135                self.create_directory(parent)?;
136            }
137        }
138        self.add_directory(path);
139        Ok(())
140    }
141    
142    fn exists(&self, path: &Path) -> Result<bool> {
143        let files = self.files.lock().unwrap();
144        let directories = self.directories.lock().unwrap();
145        
146        Ok(files.contains_key(path) || directories.contains(&path.to_path_buf()))
147    }
148    
149    fn set_modified_time(&self, path: &Path, time: SystemTime) -> Result<()> {
150        let mut files = self.files.lock().unwrap();
151        
152        if let Some(file) = files.get_mut(path) {
153            file.modified = time;
154            Ok(())
155        } else {
156            Err(FileSystemError::NotFound(path.to_path_buf()))
157        }
158    }
159}