Skip to main content

Mountain/RPC/CocoonService/FileSystem/
FindFiles.rs

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