Mountain/ApplicationState/
Internal.rs1#![allow(non_snake_case, non_camel_case_types)]
15
16use std::{collections::HashMap, fs, path::Path};
17
18use Common::Error::CommonError::CommonError;
19use log::{error, info, trace};
20use serde::{self, Deserializer, Serializer};
21use serde_json::Value;
22use url::Url;
23
24use crate::{
25 ApplicationState::{
26 ApplicationState::MapLockError,
27 DTO::ExtensionDescriptionStateDTO::ExtensionDescriptionStateDTO,
28 },
29 ExtensionManagement,
30};
31
32pub fn AnalyzeTextLinesAndEOL(TextContent:&str) -> (Vec<String>, String) {
35 let DetectedEOL = if TextContent.contains("\r\n") { "\r\n" } else { "\n" };
36
37 (
38 TextContent.split(DetectedEOL).map(String::from).collect(),
39 DetectedEOL.to_string(),
40 )
41}
42
43pub fn LoadInitialMementoFromDisk(StorageFilePath:&Path) -> HashMap<String, Value> {
46 if !StorageFilePath.exists() {
47 return HashMap::new();
48 }
49
50 match fs::read_to_string(StorageFilePath) {
51 Ok(Content) => {
52 serde_json::from_str(&Content).unwrap_or_else(|Error| {
53 error!(
54 "[AppStateInternal] Failed to parse JSON from '{}': {}. Returning empty map.",
55 StorageFilePath.display(),
56 Error
57 );
58
59 HashMap::new()
60 })
61 },
62
63 Err(Error) => {
64 error!(
65 "[AppStateInternal] Failed to read '{}': {}. Returning empty map.",
66 StorageFilePath.display(),
67 Error
68 );
69
70 HashMap::new()
71 },
72 }
73}
74
75pub fn ResolveMementoStorageFilePath(
77 ApplicationDataDirectory:&Path,
78
79 IsGlobalScope:bool,
80
81 WorkSpaceIdentifier:&str,
82) -> std::path::PathBuf {
83 let UserStorageBasePath = ApplicationDataDirectory.join("User");
84
85 if IsGlobalScope {
86 UserStorageBasePath.join("globalStorage.json")
87 } else {
88 let Segment = WorkSpaceIdentifier.replace(|c:char| !c.is_alphanumeric() && c != '-' && c != '_', "_");
90
91 UserStorageBasePath.join("workspaceStorage").join(Segment).join("storage.json")
92 }
93}
94
95pub async fn ScanAndPopulateExtensions(
98 ApplicationHandle:tauri::AppHandle,
99
100 State:&crate::ApplicationState::ApplicationState::ApplicationState,
101) -> Result<(), CommonError> {
102 info!("[AppStateInternal] Starting extension scan...");
103
104 let mut AllFoundExtensions:HashMap<String, ExtensionDescriptionStateDTO> = HashMap::new();
105
106 let ScanPaths = State.ExtensionScanPaths.lock().map_err(MapLockError)?.clone();
107
108 trace!("[AppStateInternal] Scanning paths: {:?}", ScanPaths);
109
110 for Path in ScanPaths {
111 let FoundInPath =
112 ExtensionManagement::Scanner::ScanDirectoryForExtensions(ApplicationHandle.clone(), Path).await?;
113
114 for Extension in FoundInPath {
115 let Identifier = Extension
116 .Identifier
117 .get("value")
118 .and_then(Value::as_str)
119 .unwrap_or_default()
120 .to_string();
121
122 if !Identifier.is_empty() {
123 AllFoundExtensions.insert(Identifier, Extension);
124 }
125 }
126 }
127
128 let mut ScannedExtensionsGuard = State.ScannedExtensions.lock().map_err(MapLockError)?;
129
130 *ScannedExtensionsGuard = AllFoundExtensions;
131
132 info!(
133 "[AppStateInternal] Extension scan complete. Found {} extensions.",
134 ScannedExtensionsGuard.len()
135 );
136
137 Ok(())
138}
139
140pub mod URLSerializationHelper {
143
144 use serde::Deserialize;
145
146 use super::*;
147
148 pub fn serialize<S>(URLInstance:&Url, SerializerInstance:S) -> Result<S::Ok, S::Error>
149 where
150 S: Serializer, {
151 SerializerInstance.serialize_str(URLInstance.as_str())
152 }
153
154 pub fn deserialize<'de, D>(DeserializerInstance:D) -> Result<Url, D::Error>
155 where
156 D: Deserializer<'de>, {
157 let StringValue = String::deserialize(DeserializerInstance)?;
158
159 Url::parse(&StringValue).map_err(serde::de::Error::custom)
160 }
161}