Skip to main content

Mountain/IPC/WindServiceHandlers/
Storage.rs

1#![allow(non_snake_case, unused_variables, dead_code, unused_imports)]
2
3//! Persistent storage handlers - get, set, delete, keys, bulk operations.
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 StorageGet(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
14	let key = Arguments
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 value = provider
23		.GetStorageValue(false, key)
24		.await
25		.map_err(|Error| format!("Failed to get storage item: {}", Error))?;
26
27	dev_log!("storage", "get: {}", key);
28	Ok(value.unwrap_or(Value::Null))
29}
30
31/// Handler for storage set requests
32pub async fn StorageSet(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
33	let key = Arguments
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 value = Arguments.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(value))
45		.await
46		.map_err(|Error| format!("Failed to set storage item: {}", Error))?;
47
48	dev_log!("storage", "set: {}", key);
49	Ok(Value::Null)
50}
51
52/// Delete a persistent storage key.
53pub async fn StorageDelete(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
54	let Key = Arguments
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 StorageKeys(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 StorageGetItems(RunTime:Arc<ApplicationRunTime>, _Arguments: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			// Convert JSON object to array of [key, value] tuples
89			if let Some(Obj) = State.as_object() {
90				let Tuples:Vec<Value> = Obj
91					.iter()
92					.map(|(K, V)| {
93						let ValStr = match V {
94							Value::String(S) => S.clone(),
95							_ => V.to_string(),
96						};
97						json!([K, ValStr])
98					})
99					.collect();
100				Ok(json!(Tuples))
101			} else {
102				Ok(json!([]))
103			}
104		},
105		Err(_) => Ok(json!([])),
106	}
107}
108
109/// Update storage items. VS Code sends { insert, delete } where:
110/// - insert: Array of [key, value] tuples or Map<string, string>
111/// - delete: Array of keys to remove
112pub async fn StorageUpdateItems(RunTime:Arc<ApplicationRunTime>, Arguments:Vec<Value>) -> Result<Value, String> {
113	let provider:Arc<dyn StorageProvider> = RunTime.Environment.Require();
114
115	if let Some(Updates) = Arguments.get(0).and_then(|V| V.as_object()) {
116		// Handle inserts
117		if let Some(Inserts) = Updates.get("insert") {
118			if let Some(Arr) = Inserts.as_array() {
119				for Item in Arr {
120					if let Some(Pair) = Item.as_array() {
121						if let (Some(Key), Some(Val)) = (Pair.get(0).and_then(|V| V.as_str()), Pair.get(1)) {
122							let _ = provider.UpdateStorageValue(true, Key.to_string(), Some(Val.clone())).await;
123						}
124					}
125				}
126			} else if let Some(Obj) = Inserts.as_object() {
127				for (Key, Val) in Obj {
128					let _ = provider.UpdateStorageValue(true, Key.clone(), Some(Val.clone())).await;
129				}
130			}
131		}
132
133		// Handle deletes
134		if let Some(Deletes) = Updates.get("delete").and_then(|V| V.as_array()) {
135			for Key in Deletes {
136				if let Some(K) = Key.as_str() {
137					let _ = provider.UpdateStorageValue(true, K.to_string(), None).await;
138				}
139			}
140		}
141	}
142
143	Ok(Value::Null)
144}