Skip to main content

Mountain/RPC/CocoonService/FileSystem/
FindFiles.rs

1//! Walk every workspace root collecting paths that match `pattern`
2//! (globset). Falls back to cwd when no roots are open.
3
4use globset::Glob;
5use tonic::{Response, Status};
6use ::Vine::Generated::{FindFilesRequest, FindFilesResponse};
7
8use crate::{RPC::CocoonService::CocoonServiceImpl, dev_log};
9
10pub async fn Fn(Service:&CocoonServiceImpl, Request:FindFilesRequest) -> Result<Response<FindFilesResponse>, Status> {
11	dev_log!("cocoon", "[CocoonService] Finding files with pattern: {}", Request.pattern);
12
13	let Matcher = Glob::new(&Request.pattern)
14		.map_err(|Error| {
15			Status::invalid_argument(format!("find_files: invalid pattern '{}': {}", Request.pattern, Error))
16		})?
17		.compile_matcher();
18
19	let Roots:Vec<std::path::PathBuf> = {
20		match Service.environment.ApplicationState.Workspace.WorkspaceFolders.lock() {
21			Ok(Guard) => Guard.iter().map(|F| std::path::PathBuf::from(F.URI.path())).collect(),
22
23			Err(_) => Vec::new(),
24		}
25	};
26
27	let SearchRoots = if Roots.is_empty() {
28		vec![std::env::current_dir().unwrap_or_default()]
29	} else {
30		Roots
31	};
32
33	let mut URIs = Vec::new();
34
35	fn WalkAndCollect(
36		Directory:&std::path::Path,
37
38		Root:&std::path::Path,
39
40		Matcher:&globset::GlobMatcher,
41
42		Results:&mut Vec<String>,
43	) {
44		if let Ok(Entries) = std::fs::read_dir(Directory) {
45			for Entry in Entries.flatten() {
46				let EntryPath = Entry.path();
47
48				if EntryPath.is_dir() {
49					WalkAndCollect(&EntryPath, Root, Matcher, Results);
50				} else if let Ok(Relative) = EntryPath.strip_prefix(Root) {
51					if Matcher.is_match(Relative) {
52						Results.push(format!("file://{}", EntryPath.display()));
53					}
54				}
55			}
56		}
57	}
58
59	for Root in &SearchRoots {
60		WalkAndCollect(Root, Root, &Matcher, &mut URIs);
61	}
62
63	dev_log!(
64		"cocoon",
65		"[CocoonService] find_files: {} results for pattern '{}'",
66		URIs.len(),
67		Request.pattern
68	);
69
70	Ok(Response::new(FindFilesResponse { uris:URIs }))
71}