Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
Search.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3use std::{future::Future, pin::Pin, sync::Arc};
4
5use CommonLibrary::{Environment::Requires::Requires, Search::SearchProvider::SearchProvider};
6use serde_json::{Value, json};
7use tauri::Runtime;
8
9use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect};
10
11pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
12	match MethodName {
13		"findFiles" | "findTextInFiles" => {
14			let MethodNameOwned = MethodName.to_string();
15			let effect =
16				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
17					Box::pin(async move {
18						use CommonLibrary::Workspace::WorkspaceProvider::WorkspaceProvider;
19						let provider:Arc<dyn SearchProvider> = run_time.Environment.Require();
20						// Accept three call shapes:
21						//   - `{pattern, options}` named form
22						//   - `[pattern, options]` positional from `TryMountainThenNode` Cocoon path
23						//   - `pattern` bare (legacy single-arg)
24						let Args = if let Some(Object) = Parameters.as_object() {
25							(
26								Object.get("pattern").cloned().unwrap_or_default(),
27								Object.get("options").cloned().unwrap_or_default(),
28							)
29						} else if Parameters.is_array() {
30							(
31								Parameters.get(0).cloned().unwrap_or_default(),
32								Parameters.get(1).cloned().unwrap_or_default(),
33							)
34						} else {
35							(Parameters.clone(), Value::Null)
36						};
37						let (Pattern, Options) = Args;
38						if MethodNameOwned == "findTextInFiles" {
39							return provider.TextSearch(Pattern, Options).await.map_err(|e| e.to_string());
40						}
41						// `findFiles` - delegate to
42						// `WorkspaceProvider::FindFilesInWorkspace` so we
43						// get the same `ignore`-aware glob walker that
44						// `search:fileSearch` uses. The trait returns
45						// `Vec<Url>`; map to `Vec<String>` for the wire.
46						if Pattern.is_null() {
47							return Ok(json!([]));
48						}
49						let Exclude = Options.get("exclude").cloned().filter(|V| !V.is_null());
50						let MaxResults = Options.get("maxResults").and_then(Value::as_u64).map(|N| N as usize);
51						let UseIgnoreFiles = Options.get("useIgnoreFiles").and_then(Value::as_bool).unwrap_or(true);
52						let FollowSymlinks = Options.get("followSymlinks").and_then(Value::as_bool).unwrap_or(false);
53						let Urls = run_time
54							.Environment
55							.FindFilesInWorkspace(Pattern, Exclude, MaxResults, UseIgnoreFiles, FollowSymlinks)
56							.await
57							.map_err(|Error| Error.to_string())?;
58						Ok(json!(Urls.into_iter().map(|U| U.to_string()).collect::<Vec<_>>()))
59					})
60				};
61			Some(Ok(Box::new(effect)))
62		},
63
64		"Search.TextSearch" => {
65			let effect =
66				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
67					Box::pin(async move {
68						let provider:Arc<dyn SearchProvider> = run_time.Environment.Require();
69						let query = Parameters.get(0).cloned().unwrap_or_default();
70						let options = Parameters.get(1).cloned().unwrap_or_default();
71						provider.TextSearch(query, options).await.map_err(|e| e.to_string())
72					})
73				};
74			Some(Ok(Box::new(effect)))
75		},
76
77		_ => None,
78	}
79}