Skip to main content

Mountain/Track/Effect/CreateEffectForRequest/
StatusBar.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3//! # StatusBar Effect (CreateEffectForRequest)
4//!
5//! Effect constructors for status bar RPC methods from the Cocoon extension
6//! host. Delegates to the `StatusBarProvider` trait on `MountainEnvironment`.
7//!
8//! ## Methods handled
9//!
10//! | Method | Description |
11//! |---|---|
12//! | `$statusBar:set` | Create or update a status bar entry |
13//! | `$statusBar:dispose` | Remove a status bar entry by ID |
14//! | `$setStatusBarMessage` | Set a simple text message in the status bar |
15//! | `$disposeStatusBarMessage` | Remove a status bar message by ID |
16
17use std::{future::Future, pin::Pin, sync::Arc};
18
19use CommonLibrary::{
20	Environment::Requires::Requires,
21	StatusBar::{DTO::StatusBarEntryDTO::StatusBarEntryDTO, StatusBarProvider::StatusBarProvider},
22};
23use serde_json::{Value, json};
24use tauri::Runtime;
25
26use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, Track::Effect::MappedEffectType::MappedEffect};
27
28pub fn CreateEffect<R:Runtime>(MethodName:&str, Parameters:Value) -> Option<Result<MappedEffect, String>> {
29	match MethodName {
30		"$statusBar:set" => {
31			let effect =
32				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
33					Box::pin(async move {
34						let provider:Arc<dyn StatusBarProvider> = run_time.Environment.Require();
35
36						// The extension host serialises this as an object with named fields,
37						// matching the shape used by the RPC layer (EntryIdentifier = id).
38						let entry_id = Parameters
39							.get("id")
40							.and_then(Value::as_str)
41							.ok_or_else(|| "$statusBar:set: missing 'id' field".to_string())?;
42
43						let item_id = Parameters.get("itemId").and_then(Value::as_str).unwrap_or(entry_id);
44
45						let ext_id = Parameters.get("extensionId").and_then(Value::as_str).unwrap_or("");
46
47						let text = Parameters.get("text").and_then(Value::as_str).unwrap_or("").to_string();
48
49						let tooltip = Parameters.get("tooltip").cloned();
50
51						let command = Parameters.get("command").cloned();
52
53						let color = Parameters.get("color").cloned();
54
55						let background_color = Parameters.get("backgroundColor").cloned();
56
57						let is_aligned_left = Parameters.get("alignLeft").and_then(Value::as_bool).unwrap_or(false);
58
59						let priority = Parameters.get("priority").and_then(Value::as_f64);
60
61						let accessibility = Parameters.get("accessibilityInformation").cloned();
62
63						let entry = StatusBarEntryDTO {
64							EntryIdentifier:entry_id.to_string(),
65							ItemIdentifier:item_id.to_string(),
66							ExtensionIdentifier:ext_id.to_string(),
67							Name:None,
68							Text:text,
69							Tooltip:tooltip,
70							HasTooltipProvider:false,
71							Command:command,
72							Color:color,
73							BackgroundColor:background_color,
74							IsAlignedLeft:is_aligned_left,
75							Priority:priority,
76							AccessibilityInformation:accessibility,
77						};
78
79						provider
80							.SetStatusBarEntry(entry)
81							.await
82							.map(|_| json!(null))
83							.map_err(|e| e.to_string())
84					})
85				};
86
87			Some(Ok(Box::new(effect)))
88		},
89
90		"$statusBar:dispose" => {
91			let effect =
92				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
93					Box::pin(async move {
94						let provider:Arc<dyn StatusBarProvider> = run_time.Environment.Require();
95
96						// Require a non-empty id - a missing id would silently target the
97						// wrong entry (previously fell back to the literal string "id").
98						let id = Parameters
99							.get(0)
100							.and_then(Value::as_str)
101							.filter(|s| !s.is_empty())
102							.ok_or_else(|| "$statusBar:dispose: missing or empty entry id".to_string())?;
103
104						provider
105							.DisposeStatusBarEntry(id.to_string())
106							.await
107							.map(|_| json!(null))
108							.map_err(|e| e.to_string())
109					})
110				};
111
112			Some(Ok(Box::new(effect)))
113		},
114
115		"$setStatusBarMessage" => {
116			let effect =
117				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
118					Box::pin(async move {
119						let provider:Arc<dyn StatusBarProvider> = run_time.Environment.Require();
120
121						let message_id = Parameters
122							.get(0)
123							.and_then(Value::as_str)
124							.filter(|s| !s.is_empty())
125							.ok_or_else(|| "$setStatusBarMessage: missing or empty message id".to_string())?;
126
127						let text = Parameters.get(1).and_then(Value::as_str).unwrap_or("").to_string();
128
129						provider
130							.SetStatusBarMessage(message_id.to_string(), text)
131							.await
132							.map(|_| json!(null))
133							.map_err(|e| e.to_string())
134					})
135				};
136
137			Some(Ok(Box::new(effect)))
138		},
139
140		"$disposeStatusBarMessage" => {
141			let effect =
142				move |run_time:Arc<ApplicationRunTime>| -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
143					Box::pin(async move {
144						let provider:Arc<dyn StatusBarProvider> = run_time.Environment.Require();
145
146						let message_id = Parameters
147							.get(0)
148							.and_then(Value::as_str)
149							.filter(|s| !s.is_empty())
150							.ok_or_else(|| "$disposeStatusBarMessage: missing or empty message id".to_string())?;
151
152						provider
153							.DisposeStatusBarMessage(message_id.to_string())
154							.await
155							.map(|_| json!(null))
156							.map_err(|e| e.to_string())
157					})
158				};
159
160			Some(Ok(Box::new(effect)))
161		},
162
163		_ => None,
164	}
165}