Skip to main content

Mountain/IPC/WindServiceHandlers/UI/
QuickInputShowQuickPick.rs

1//! Wire method: `quickInput:showQuickPick`.
2
3use std::sync::Arc;
4
5use serde_json::{Value, json};
6
7use crate::RunTime::ApplicationRunTime::ApplicationRunTime;
8
9pub async fn Fn(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
10	use CommonLibrary::UserInterface::{
11		DTO::{QuickPickItemDTO::QuickPickItemDTO, QuickPickOptionsDTO::QuickPickOptionsDTO},
12		UserInterfaceProvider::UserInterfaceProvider,
13	};
14
15	let Items:Vec<QuickPickItemDTO> = Arguments
16		.first()
17		.and_then(|V| V.as_array())
18		.map(|Arr| {
19			Arr.iter()
20				.filter_map(|Item| {
21					let Label = Item.get("label").and_then(|L| L.as_str()).unwrap_or("").to_string();
22
23					let Description = Item.get("description").and_then(|D| D.as_str()).map(|S| S.to_string());
24
25					let Detail = Item.get("detail").and_then(|D| D.as_str()).map(|S| S.to_string());
26
27					let Picked = Item.get("picked").and_then(|P| P.as_bool()).unwrap_or(false);
28
29					Some(QuickPickItemDTO { Label, Description, Detail, Picked:Some(Picked), AlwaysShow:Some(false) })
30				})
31				.collect()
32		})
33		.unwrap_or_default();
34
35	let Options = QuickPickOptionsDTO {
36		PlaceHolder:Arguments
37			.get(1)
38			.and_then(|V| V.get("placeholder"))
39			.and_then(|P| P.as_str())
40			.map(|S| S.to_string()),
41
42		CanPickMany:Some(
43			Arguments
44				.get(1)
45				.and_then(|V| V.get("canPickMany"))
46				.and_then(|B| B.as_bool())
47				.unwrap_or(false),
48		),
49
50		Title:Arguments
51			.get(1)
52			.and_then(|V| V.get("title"))
53			.and_then(|T| T.as_str())
54			.map(|S| S.to_string()),
55		..Default::default()
56	};
57
58	// Extract before move into ShowQuickPick.
59	let CanPickMany = Options.CanPickMany == Some(true);
60
61	let Result = RunTime
62		.Environment
63		.ShowQuickPick(Items, Some(Options))
64		.await
65		.map_err(|Error| format!("quickInput:showQuickPick failed: {}", Error))?;
66
67	match Result {
68		// When canPickMany is true, VS Code expects an array; otherwise a
69		// single string. .next() was always returning only the first item
70		// even for multi-select, silently discarding all other selections.
71		Some(Labels) => {
72			if CanPickMany {
73				Ok(json!(Labels))
74			} else {
75				Ok(Labels.into_iter().next().map(|S| json!(S)).unwrap_or(Value::Null))
76			}
77		},
78
79		None => Ok(Value::Null),
80	}
81}