Skip to main content

Mountain/IPC/WindServiceHandler/
Storage.rs

1#![allow(non_snake_case)]
2
3//! Storage domain handlers for Wind IPC.
4
5use std::sync::Arc;
6
7use serde_json::{Value, json};
8use CommonLibrary::{Environment::Requires::Requires, Storage::StorageProvider::StorageProvider};
9
10use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
11
12/// Handler for storage get requests
13pub async fn handle_storage_get(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
14	let Key = Args
15		.get(0)
16		.ok_or("Missing storage key".to_string())?
17		.as_str()
18		.ok_or("Storage key must be a string".to_string())?;
19
20	let Provider:Arc<dyn StorageProvider> = Runtime.Environment.Require();
21
22	let StorageValue = Provider
23		.GetStorageValue(false, Key)
24		.await
25		.map_err(|E| format!("Failed to get storage item: {}", E))?;
26
27	dev_log!("storage", "get: {}", Key);
28	Ok(StorageValue.unwrap_or(Value::Null))
29}
30
31/// Handler for storage set requests
32pub async fn handle_storage_set(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
33	let Key = Args
34		.get(0)
35		.ok_or("Missing storage key".to_string())?
36		.as_str()
37		.ok_or("Storage key must be a string".to_string())?;
38
39	let StorageValue = Args.get(1).ok_or("Missing storage value".to_string())?.clone();
40
41	let Provider:Arc<dyn StorageProvider> = Runtime.Environment.Require();
42
43	Provider
44		.UpdateStorageValue(false, Key.to_string(), Some(StorageValue))
45		.await
46		.map_err(|E| format!("Failed to set storage item: {}", E))?;
47
48	dev_log!("storage", "set: {}", Key);
49	Ok(Value::Null)
50}
51
52/// Delete a persistent storage key.
53pub async fn handle_storage_delete(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
54	let Key = Args
55		.first()
56		.and_then(|V| V.as_str())
57		.ok_or("storage:delete requires key as first argument".to_string())?
58		.to_string();
59
60	Runtime
61		.Environment
62		.UpdateStorageValue(true, Key, None)
63		.await
64		.map_err(|Error| format!("storage:delete failed: {}", Error))?;
65
66	Ok(Value::Null)
67}
68
69/// Return all storage keys.
70pub async fn handle_storage_keys(Runtime:Arc<ApplicationRunTime>) -> Result<Value, String> {
71	let Storage = Runtime
72		.Environment
73		.GetAllStorage(true)
74		.await
75		.map_err(|Error| format!("storage:keys failed: {}", Error))?;
76
77	let Keys:Vec<String> = Storage.as_object().map(|O| O.keys().cloned().collect()).unwrap_or_default();
78	Ok(json!(Keys))
79}
80
81/// Get all storage items as [key, value] tuples.
82/// VS Code's NativeWorkbenchStorageService calls this on initialization.
83pub async fn handle_storage_get_items(Runtime:Arc<ApplicationRunTime>, _Args:Vec<Value>) -> Result<Value, String> {
84	let Provider:Arc<dyn StorageProvider> = Runtime.Environment.Require();
85
86	match Provider.GetAllStorage(true).await {
87		Ok(State) => {
88			if let Some(Obj) = State.as_object() {
89				let Tuples:Vec<Value> = Obj
90					.iter()
91					.map(|(K, V)| {
92						let ValStr = match V {
93							Value::String(S) => S.clone(),
94							_ => V.to_string(),
95						};
96						json!([K, ValStr])
97					})
98					.collect();
99				Ok(json!(Tuples))
100			} else {
101				Ok(json!([]))
102			}
103		},
104		Err(_) => Ok(json!([])),
105	}
106}
107
108/// Update storage items. VS Code sends { insert, delete } where:
109/// - insert: Array of [key, value] tuples or Map<string, string>
110/// - delete: Array of keys to remove
111pub async fn handle_storage_update_items(Runtime:Arc<ApplicationRunTime>, Args:Vec<Value>) -> Result<Value, String> {
112	let Provider:Arc<dyn StorageProvider> = Runtime.Environment.Require();
113
114	if let Some(Updates) = Args.get(0).and_then(|V| V.as_object()) {
115		// Handle inserts
116		if let Some(Inserts) = Updates.get("insert") {
117			if let Some(Arr) = Inserts.as_array() {
118				for Item in Arr {
119					if let Some(Pair) = Item.as_array() {
120						if let (Some(Key), Some(Val)) = (Pair.get(0).and_then(|V| V.as_str()), Pair.get(1)) {
121							let _ = Provider.UpdateStorageValue(true, Key.to_string(), Some(Val.clone())).await;
122						}
123					}
124				}
125			} else if let Some(Obj) = Inserts.as_object() {
126				for (Key, Val) in Obj {
127					let _ = Provider.UpdateStorageValue(true, Key.clone(), Some(Val.clone())).await;
128				}
129			}
130		}
131
132		// Handle deletes
133		if let Some(Deletes) = Updates.get("delete").and_then(|V| V.as_array()) {
134			for Key in Deletes {
135				if let Some(K) = Key.as_str() {
136					let _ = Provider.UpdateStorageValue(true, K.to_string(), None).await;
137				}
138			}
139		}
140	}
141
142	Ok(Value::Null)
143}