Skip to main content

Mountain/ExtensionManagement/
DefaultConfigurations.rs

1#![allow(unused_variables, dead_code, unused_imports)]
2
3//! Collects default configuration values contributed by all scanned
4//! extensions. Walks each extension's `contributes.configuration.properties`
5//! tree, handles `properties`-nested sub-objects recursively, and merges
6//! everything into a single flat `{key → defaultValue}` JSON object.
7//!
8//! Circular-reference detection prevents infinite recursion on malformed
9//! extension manifests.
10
11use CommonLibrary::Error::CommonError::CommonError;
12use serde_json::{Map, Value};
13
14use crate::{ApplicationState::State::ApplicationState::ApplicationState, Environment::Utility};
15
16/// Merge default configuration values from all scanned extensions into one
17/// flat `{key → defaultValue}` JSON object. Keys use dot-notation
18/// (e.g. `editor.fontSize`). Sub-`properties` objects are recursed into.
19pub fn CollectDefaultConfigurations(State:&ApplicationState) -> Result<Value, CommonError> {
20	let mut MergedDefaults = Map::new();
21
22	let Extensions = State
23		.Extension
24		.ScannedExtensions
25		.ScannedExtensions
26		.lock()
27		.map_err(Utility::ErrorMapping::MapApplicationStateLockErrorToCommonError)?;
28
29	for Extension in Extensions.values() {
30		if let Some(contributes) = Extension.Contributes.as_ref().and_then(|v| v.as_object()) {
31			if let Some(configuration) = contributes.get("configuration").and_then(|v| v.as_object()) {
32				if let Some(properties) = configuration.get("properties").and_then(|v| v.as_object()) {
33					process_configuration_properties(&mut MergedDefaults, "", properties, &mut Vec::new())?;
34				}
35			}
36		}
37	}
38
39	Ok(Value::Object(MergedDefaults))
40}
41
42/// Recursively process `contributes.configuration.properties` nodes.
43/// - Leaf nodes with a `"default"` field contribute their value directly.
44/// - Inner nodes with a `"properties"` field are recursed with the accumulated
45///   dot-notation path.
46/// - `visited_keys` guards against circular references.
47pub fn process_configuration_properties(
48	merged_defaults:&mut Map<String, Value>,
49
50	current_path:&str,
51
52	properties:&Map<String, Value>,
53
54	visited_keys:&mut Vec<String>,
55) -> Result<(), CommonError> {
56	for (key, value) in properties {
57		let full_path = if current_path.is_empty() {
58			key.clone()
59		} else {
60			format!("{}.{}", current_path, key)
61		};
62
63		if visited_keys.contains(&full_path) {
64			return Err(CommonError::Unknown {
65				Description:format!("Circular reference detected in configuration properties: {}", full_path),
66			});
67		}
68
69		visited_keys.push(full_path.clone());
70
71		if let Some(prop_details) = value.as_object() {
72			if let Some(nested_properties) = prop_details.get("properties").and_then(|v| v.as_object()) {
73				process_configuration_properties(merged_defaults, &full_path, nested_properties, visited_keys)?;
74			} else if let Some(default_value) = prop_details.get("default") {
75				merged_defaults.insert(full_path.clone(), default_value.clone());
76			}
77		}
78
79		visited_keys.retain(|k| k != &full_path);
80	}
81
82	Ok(())
83}