| 60 | } |
| 61 | |
| 62 | async fn list_dir(&self, path: &WorkspacePath) -> WorkspaceResult<Vec<WorkspaceDirEntry>> { |
| 63 | let prefix = if path.is_root() { |
| 64 | String::new() |
| 65 | } else { |
| 66 | format!("{}/", path.as_str()) |
| 67 | }; |
| 68 | let files = self.files.read().unwrap(); |
| 69 | let mut entries = HashMap::<String, WorkspaceDirEntry>::new(); |
| 70 | |
| 71 | for (file_path, content) in files.iter() { |
| 72 | if !file_path.starts_with(&prefix) { |
| 73 | continue; |
| 74 | } |
| 75 | |
| 76 | let remaining = &file_path[prefix.len()..]; |
| 77 | if remaining.is_empty() { |
| 78 | continue; |
| 79 | } |
| 80 | |
| 81 | let (name, kind, size) = match remaining.split_once('/') { |
| 82 | Some((dir, _)) => (dir.to_string(), WorkspaceFileType::Directory, 0), |
| 83 | None => ( |
| 84 | remaining.to_string(), |
| 85 | WorkspaceFileType::File, |
| 86 | content.len() as u64, |
| 87 | ), |
| 88 | }; |
| 89 | |
| 90 | entries |
| 91 | .entry(name.clone()) |
| 92 | .or_insert(WorkspaceDirEntry { name, kind, size }); |
| 93 | } |
| 94 | |
| 95 | Ok(entries.into_values().collect()) |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | #[async_trait] |