Mountain/ApplicationState/Internal/ExtensionScanner/
ScanAndPopulateExtensions.rs

1//! # ScanAndPopulateExtensions Module (Internal)
2//!
3//! ## RESPONSIBILITIES
4//! Scans all registered extension paths for valid extensions and populates the
5//! state with discovered extensions.
6//!
7//! ## ARCHITECTURAL ROLE
8//! ScanAndPopulateExtensions is part of the **Internal::ExtensionScanner**
9//! module, handling extension discovery and population.
10//!
11//! ## KEY COMPONENTS
12//! - ScanAndPopulateExtensions: Main function for scanning extensions
13//! - ScanExtensionsWithRecovery: Robust scanning with recovery
14//!
15//! ## ERROR HANDLING
16//! - Returns Result with CommonError on failure
17//! - Handles partial failures gracefully
18//! - Comprehensive error logging
19//!
20//! ## LOGGING
21//! Operations are logged at appropriate levels (info, debug, warn, error).
22//!
23//! ## PERFORMANCE CONSIDERATIONS
24//! - Async operations for scanning
25//! - Handles multiple scan paths
26//! - Partial failure handling
27//!
28//! ## TODO
29//! - [ ] Add concurrent scanning
30//! - [ ] Implement extension caching
31//! - [ ] Add extension validation rules
32
33use std::{collections::HashMap, path::PathBuf};
34
35use CommonLibrary::Error::CommonError::CommonError;
36use log::{debug, error, info, trace, warn};
37use serde_json::Value;
38use tauri::AppHandle;
39
40use crate::{ApplicationState::DTO::ExtensionDescriptionStateDTO::ExtensionDescriptionStateDTO, ExtensionManagement};
41
42/// Scans all registered extension paths for valid extensions and populates the
43/// state.
44///
45/// # Arguments
46/// * `ApplicationHandle` - Tauri application handle for extension management
47/// * `State` - Reference to the application state
48///
49/// # Returns
50/// Result indicating success or CommonError on failure
51///
52/// # Behavior
53/// - Scans all registered extension paths
54/// - Populates state with discovered extensions
55/// - Returns comprehensive scan statistics
56/// - Handles partial failures gracefully
57pub async fn ScanAndPopulateExtensions(
58	ApplicationHandle:AppHandle,
59	_State:&crate::ApplicationState::ExtensionState::State::State,
60) -> Result<(), CommonError> {
61	info!("[ExtensionScanner] Starting extension scan...");
62
63	let mut all_found_extensions:HashMap<String, ExtensionDescriptionStateDTO> = HashMap::new();
64
65	// Note: This would need to be adapted to the new state structure
66	// For now, this is a placeholder showing the structure
67	let scan_paths:Vec<PathBuf> = Vec::new(); // Would get from State.Registry.Extension.Registry.ExtensionScanPaths
68
69	trace!("[ExtensionScanner] Scanning paths: {:?}", scan_paths);
70
71	let mut successful_scans = 0;
72	let mut failed_scans = 0;
73
74	for path in scan_paths {
75		let path_clone = path.clone();
76		match ExtensionManagement::Scanner::ScanDirectoryForExtensions(ApplicationHandle.clone(), path_clone).await {
77			Ok(found_in_path) => {
78				successful_scans += 1;
79				for extension in found_in_path {
80					let identifier = extension
81						.Identifier
82						.get("value")
83						.and_then(Value::as_str)
84						.unwrap_or_default()
85						.to_string();
86
87					if !identifier.is_empty() {
88						all_found_extensions.insert(identifier, extension);
89					}
90				}
91			},
92			Err(error) => {
93				failed_scans += 1;
94				warn!(
95					"[ExtensionScanner] Failed to scan extension path '{}': {}",
96					path.display(),
97					error
98				);
99			},
100		}
101	}
102
103	// Note: Would populate
104	// State.Extension.ScannedExtensions.Extension.ScannedExtensions
105	debug!(
106		"[ExtensionScanner] Extension scan complete. Found {} extensions ({} successful scans, {} failed scans).",
107		all_found_extensions.len(),
108		successful_scans,
109		failed_scans
110	);
111
112	if failed_scans > 0 {
113		warn!("[ExtensionScanner] {} extension paths failed to scan", failed_scans);
114	}
115
116	Ok(())
117}
118
119/// Robust extension scanning with comprehensive error handling.
120///
121/// # Arguments
122/// * `ApplicationHandle` - Tauri application handle for extension management
123/// * `State` - Reference to the application state
124///
125/// # Returns
126/// Result indicating success or CommonError on failure
127///
128/// # Behavior
129/// - Clears potentially corrupted extension state first
130/// - Performs the scan
131/// - Retries once on failure
132/// - Comprehensive error logging
133pub async fn ScanExtensionsWithRecovery(
134	ApplicationHandle:AppHandle,
135	State:&crate::ApplicationState::ExtensionState::State::State,
136) -> Result<(), CommonError> {
137	info!("[ExtensionScanner] Starting robust extension scan with recovery...");
138
139	// Clear potentially corrupted extension state first
140	// Note: Would clear
141	// State.Extension.ScannedExtensions.Extension.ScannedExtensions
142
143	// Perform the scan
144	match ScanAndPopulateExtensions(ApplicationHandle.clone(), State).await {
145		Ok(()) => {
146			info!("[ExtensionScanner] Robust extension scan completed successfully");
147			Ok(())
148		},
149		Err(error) => {
150			error!("[ExtensionScanner] Robust extension scan failed: {}", error);
151			// Attempt recovery by clearing state and retrying once
152			warn!("[ExtensionScanner] Attempting recovery from extension scan failure...");
153
154			// Clear state again
155			// Note: Would clear
156			// State.Extension.ScannedExtensions.Extension.ScannedExtensions
157
158			// Retry the scan with a cloned handle
159			ScanAndPopulateExtensions(ApplicationHandle.clone(), State).await
160		},
161	}
162}