1use crate::{FileMetadata, FileType, Vfs, WritableVfs};
2use oak_core::source::SourceText;
3use std::{
4 collections::HashMap,
5 sync::{Arc, RwLock},
6};
7
8#[derive(Default, Clone)]
11pub struct MemoryVfs {
12 files: Arc<RwLock<HashMap<String, FileEntry>>>,
13}
14
15struct FileEntry {
16 content: String,
17 modified: u64,
18}
19
20impl MemoryVfs {
21 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn write_file(&self, uri: &str, content: String) {
28 let mut files = self.files.write().unwrap();
29 files.insert(uri.to_string(), FileEntry { content, modified: Self::now() });
30 }
31
32 pub fn remove_file(&self, uri: &str) {
34 let mut files = self.files.write().unwrap();
35 files.remove(uri);
36 }
37
38 fn now() -> u64 {
39 #[cfg(not(target_arch = "wasm32"))]
42 {
43 std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs()
44 }
45 #[cfg(target_arch = "wasm32")]
46 {
47 0 }
49 }
50}
51
52impl Vfs for MemoryVfs {
53 type Source = SourceText;
54
55 fn get_source(&self, uri: &str) -> Option<SourceText> {
56 let files = self.files.read().unwrap();
57 files.get(uri).map(|entry| SourceText::new(entry.content.clone()))
58 }
59
60 fn exists(&self, uri: &str) -> bool {
61 self.files.read().unwrap().contains_key(uri)
62 }
63
64 fn metadata(&self, uri: &str) -> Option<FileMetadata> {
65 let files = self.files.read().unwrap();
66 files.get(uri).map(|entry| FileMetadata { file_type: FileType::File, len: entry.content.len() as u64, modified: Some(entry.modified) })
67 }
68
69 fn read_dir(&self, _uri: &str) -> Option<Vec<String>> {
70 let files = self.files.read().unwrap();
73 Some(files.keys().cloned().collect())
74 }
75}
76
77impl WritableVfs for MemoryVfs {
78 fn write_file(&self, uri: &str, content: String) {
79 self.write_file(uri, content);
80 }
81
82 fn remove_file(&self, uri: &str) {
83 self.remove_file(uri);
84 }
85}