From 029eb6704380643ddac21928f48d5bf7e9bb8cb7 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Mon, 22 Apr 2024 18:38:34 -0400 Subject: [PATCH] Add `SettingsSources::::json_merge_with` function (#10869) This PR adds a `json_merge_with` function to `SettingsSources::` to allow JSON merging settings from custom sources. This should help avoid repeating the actual merging logic when all that needs to be customized is which sources are being respected. Release Notes: - N/A --- crates/extension/src/extension_settings.rs | 9 +++------ crates/settings/src/settings_store.rs | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/crates/extension/src/extension_settings.rs b/crates/extension/src/extension_settings.rs index c11a6622b88456cb8ddb294e8c0400ea724cb6a2..a2ab7ac9cca73b1b2ecddd05df786c301228f2c7 100644 --- a/crates/extension/src/extension_settings.rs +++ b/crates/extension/src/extension_settings.rs @@ -5,7 +5,6 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; use std::sync::Arc; -use util::merge_non_null_json_value_into; #[derive(Deserialize, Serialize, Debug, Default, Clone, JsonSchema)] pub struct ExtensionSettings { @@ -42,10 +41,8 @@ impl Settings for ExtensionSettings { type FileContent = Self; fn load(sources: SettingsSources, _cx: &mut AppContext) -> Result { - let mut merged = serde_json::Value::Null; - for value in [sources.default].into_iter().chain(sources.user) { - merge_non_null_json_value_into(serde_json::to_value(value).unwrap(), &mut merged); - } - Ok(serde_json::from_value(merged)?) + SettingsSources::::json_merge_with( + [sources.default].into_iter().chain(sources.user), + ) } } diff --git a/crates/settings/src/settings_store.rs b/crates/settings/src/settings_store.rs index cdc2640092fc59d54437d89184236bb3134579b6..a6bb5838f9c501b72f6d7aed24bee40a10d01dcd 100644 --- a/crates/settings/src/settings_store.rs +++ b/crates/settings/src/settings_store.rs @@ -116,17 +116,26 @@ impl<'a, T: Serialize> SettingsSources<'a, T> { .chain(self.project.iter().copied()) } - /// Returns the settings after performing a JSON merge of the customizations into the - /// default settings. + /// Returns the settings after performing a JSON merge of the provided customizations. /// - /// More-specific customizations win out over the less-specific ones. - pub fn json_merge(&self) -> Result { + /// Customizations later in the iterator win out over the earlier ones. + pub fn json_merge_with( + customizations: impl Iterator, + ) -> Result { let mut merged = serde_json::Value::Null; - for value in self.defaults_and_customizations() { + for value in customizations { merge_non_null_json_value_into(serde_json::to_value(value).unwrap(), &mut merged); } Ok(serde_json::from_value(merged)?) } + + /// Returns the settings after performing a JSON merge of the customizations into the + /// default settings. + /// + /// More-specific customizations win out over the less-specific ones. + pub fn json_merge(&'a self) -> Result { + Self::json_merge_with(self.defaults_and_customizations()) + } } #[derive(Clone, Copy)]