Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
UserInterface.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3//! # UserInterface Effect (CreateEffectForRequest)
4//!
5//! Effect constructors for user-interface dialog methods. Delegates to the
6//! `UserInterfaceProvider` trait on `MountainEnvironment` for all UI
7//! interactions.
8//!
9//! ## Methods handled
10//!
11//! | Method | Description |
12//! |---|---|
13//! | `UserInterface.ShowMessage` | Show a notification with optional severity |
14//! | `UserInterface.ShowQuickPick` | Display a quick-pick selection list |
15//! | `UserInterface.ShowInputBox` | Display a text input dialog |
16//! | `UserInterface.ShowOpenDialog` | Display a file/folder picker dialog |
17//! | `UserInterface.ShowSaveDialog` | Display a save file dialog |
18
19use std::{future::Future, pin::Pin, sync::Arc};
20
21use CommonLibrary::{
22	Environment::Requires::Requires,
23	UserInterface::{DTO::MessageSeverity::MessageSeverity, UserInterfaceProvider::UserInterfaceProvider},
24};
25use serde_json::{Value, json};
26use tauri::Runtime;
27
28use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect, dev_log};
29
30pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
31	match MethodName {
32		"UserInterface.ShowMessage" => {
33			let effect =
34				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
35					Box::pin(async move {
36						let provider:Arc<dyn UserInterfaceProvider> = run_time.Environment.Require();
37						let severity_str = Parameters.get(0).and_then(Value::as_str).unwrap_or("info");
38						let message = Parameters.get(1).and_then(Value::as_str).unwrap_or("").to_string();
39						let options = Parameters.get(2).cloned();
40						let severity = match severity_str {
41							"warning" => MessageSeverity::Warning,
42							"error" => MessageSeverity::Error,
43							_ => MessageSeverity::Info,
44						};
45						provider
46							.ShowMessage(severity, message, options)
47							.await
48							.map(|_| json!(null))
49							.map_err(|e| e.to_string())
50					})
51				};
52
53			Some(Ok(Box::new(effect)))
54		},
55
56		"UserInterface.ShowQuickPick" => {
57			let effect =
58				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
59					Box::pin(async move {
60						let provider:Arc<dyn UserInterfaceProvider> = run_time.Environment.Require();
61						let items = Parameters
62							.get(0)
63							.and_then(Value::as_array)
64							.cloned()
65							.unwrap_or_default()
66							.into_iter()
67							.filter_map(|v| {
68								serde_json::from_value::<
69									CommonLibrary::UserInterface::DTO::QuickPickItemDTO::QuickPickItemDTO,
70								>(v)
71								.ok()
72							})
73							.collect::<Vec<_>>();
74						let options = Parameters.get(1).and_then(|V| {
75							if V.is_object() {
76								match serde_json::from_value::<
77									CommonLibrary::UserInterface::DTO::QuickPickOptionsDTO::QuickPickOptionsDTO,
78								>(V.clone())
79								{
80									Ok(dto) => Some(dto),
81									Err(e) => {
82										dev_log!("ipc", "warn: Failed to deserialize QuickPickOptionsDTO: {}", e);
83										Some(Default::default())
84									},
85								}
86							} else {
87								None
88							}
89						});
90						provider
91							.ShowQuickPick(items, options)
92							.await
93							.map(|selected_items| json!(selected_items))
94							.map_err(|e| e.to_string())
95					})
96				};
97
98			Some(Ok(Box::new(effect)))
99		},
100
101		"UserInterface.ShowInputBox" => {
102			let effect =
103				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
104					Box::pin(async move {
105						let provider:Arc<dyn UserInterfaceProvider> = run_time.Environment.Require();
106						let options = if let Some(Value::Object(obj)) = Parameters.get(0) {
107							match serde_json::from_value::<
108								CommonLibrary::UserInterface::DTO::InputBoxOptionsDTO::InputBoxOptionsDTO,
109							>(Value::Object(obj.clone()))
110							{
111								Ok(dto) => Some(dto),
112								Err(e) => {
113									dev_log!("ipc", "warn: Failed to deserialize InputBoxOptionsDTO: {}", e);
114									Some(
115										CommonLibrary::UserInterface::DTO::InputBoxOptionsDTO::InputBoxOptionsDTO::default(),
116									)
117								},
118							}
119						} else {
120							None
121						};
122						provider
123							.ShowInputBox(options)
124							.await
125							.map(|input_opt| json!(input_opt))
126							.map_err(|e| e.to_string())
127					})
128				};
129
130			Some(Ok(Box::new(effect)))
131		},
132
133		"UserInterface.ShowOpenDialog" => {
134			let effect =
135				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
136					Box::pin(async move {
137						let provider:Arc<dyn UserInterfaceProvider> = run_time.Environment.Require();
138						let options = if let Some(Value::Object(obj)) = Parameters.get(0) {
139							match serde_json::from_value::<
140								CommonLibrary::UserInterface::DTO::OpenDialogOptionsDTO::OpenDialogOptionsDTO,
141							>(Value::Object(obj.clone()))
142							{
143								Ok(dto) => Some(dto),
144								Err(e) => {
145									dev_log!("ipc", "warn: Failed to deserialize OpenDialogOptionsDTO: {}", e);
146									Some(Default::default())
147								},
148							}
149						} else {
150							None
151						};
152						provider
153							.ShowOpenDialog(options)
154							.await
155							.map(|path_buf_opt| json!(path_buf_opt))
156							.map_err(|e| e.to_string())
157					})
158				};
159
160			Some(Ok(Box::new(effect)))
161		},
162
163		"UserInterface.ShowSaveDialog" => {
164			let effect =
165				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
166					Box::pin(async move {
167						let provider:Arc<dyn UserInterfaceProvider> = run_time.Environment.Require();
168						let options = if let Some(Value::Object(obj)) = Parameters.get(0) {
169							match serde_json::from_value::<
170								CommonLibrary::UserInterface::DTO::SaveDialogOptionsDTO::SaveDialogOptionsDTO,
171							>(Value::Object(obj.clone()))
172							{
173								Ok(dto) => Some(dto),
174								Err(e) => {
175									dev_log!("ipc", "warn: Failed to deserialize SaveDialogOptionsDTO: {}", e);
176									Some(Default::default())
177								},
178							}
179						} else {
180							None
181						};
182						provider
183							.ShowSaveDialog(options)
184							.await
185							.map(|path_buf_opt| json!(path_buf_opt))
186							.map_err(|e| e.to_string())
187					})
188				};
189
190			Some(Ok(Box::new(effect)))
191		},
192
193		_ => None,
194	}
195}