Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/ExtensionManagement/
DefaultConfigurations.rs

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