Fallible Settings (#42938)

Also tidies up error notifications so that in the case of syntax errors
we don't see noise about the migration failing as well.

Release Notes:

- Invalid values in settings files will no longer prevent the rest of
the file from being parsed.
This commit is contained in:
Conrad Irwin
2025-11-21 08:28:17 -07:00
committed by GitHub
parent a8d7f06b47
commit 2ac13b9489
19 changed files with 509 additions and 494 deletions
+23 -33
View File
@@ -4,90 +4,72 @@ use schemars::{JsonSchema, JsonSchema_repr};
use serde::{Deserialize, Deserializer, Serialize};
use serde_json::Value;
use serde_repr::{Deserialize_repr, Serialize_repr};
use settings_macros::MergeFrom;
use settings_macros::{MergeFrom, with_fallible_options};
use std::{fmt::Display, sync::Arc};
use serde_with::skip_serializing_none;
use crate::serialize_f32_with_two_decimal_places;
/// Settings for rendering text in UI and text buffers.
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
pub struct ThemeSettingsContent {
/// The default font size for text in the UI.
#[serde(default)]
#[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
pub ui_font_size: Option<f32>,
/// The name of a font to use for rendering in the UI.
#[serde(default)]
pub ui_font_family: Option<FontFamilyName>,
/// The font fallbacks to use for rendering in the UI.
#[serde(default)]
#[schemars(default = "default_font_fallbacks")]
#[schemars(extend("uniqueItems" = true))]
pub ui_font_fallbacks: Option<Vec<FontFamilyName>>,
/// The OpenType features to enable for text in the UI.
#[serde(default)]
#[schemars(default = "default_font_features")]
pub ui_font_features: Option<FontFeatures>,
/// The weight of the UI font in CSS units from 100 to 900.
#[serde(default)]
#[schemars(default = "default_buffer_font_weight")]
pub ui_font_weight: Option<FontWeight>,
/// The name of a font to use for rendering in text buffers.
#[serde(default)]
pub buffer_font_family: Option<FontFamilyName>,
/// The font fallbacks to use for rendering in text buffers.
#[serde(default)]
#[schemars(extend("uniqueItems" = true))]
pub buffer_font_fallbacks: Option<Vec<FontFamilyName>>,
/// The default font size for rendering in text buffers.
#[serde(default)]
#[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
pub buffer_font_size: Option<f32>,
/// The weight of the editor font in CSS units from 100 to 900.
#[serde(default)]
#[schemars(default = "default_buffer_font_weight")]
pub buffer_font_weight: Option<FontWeight>,
/// The buffer's line height.
#[serde(default)]
pub buffer_line_height: Option<BufferLineHeight>,
/// The OpenType features to enable for rendering in text buffers.
#[serde(default)]
#[schemars(default = "default_font_features")]
pub buffer_font_features: Option<FontFeatures>,
/// The font size for agent responses in the agent panel. Falls back to the UI font size if unset.
#[serde(default)]
#[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
pub agent_ui_font_size: Option<f32>,
/// The font size for user messages in the agent panel.
#[serde(default)]
#[serde(serialize_with = "crate::serialize_optional_f32_with_two_decimal_places")]
pub agent_buffer_font_size: Option<f32>,
/// The name of the Zed theme to use.
#[serde(default)]
pub theme: Option<ThemeSelection>,
/// The name of the icon theme to use.
#[serde(default)]
pub icon_theme: Option<IconThemeSelection>,
/// UNSTABLE: Expect many elements to be broken.
///
// Controls the density of the UI.
#[serde(rename = "unstable.ui_density", default)]
#[serde(rename = "unstable.ui_density")]
pub ui_density: Option<UiDensity>,
/// How much to fade out unused code.
#[serde(default)]
#[schemars(range(min = 0.0, max = 0.9))]
pub unnecessary_code_fade: Option<CodeFade>,
/// EXPERIMENTAL: Overrides for the current theme.
///
/// These values will override the ones on the current theme specified in `theme`.
#[serde(rename = "experimental.theme_overrides", default)]
#[serde(rename = "experimental.theme_overrides")]
pub experimental_theme_overrides: Option<ThemeStyleContent>,
/// Overrides per theme
@@ -270,7 +252,7 @@ impl UiDensity {
}
/// Font family name.
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
#[serde(transparent)]
pub struct FontFamilyName(pub Arc<str>);
@@ -345,11 +327,11 @@ where
}
/// The content of a serialized theme.
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
#[serde(default)]
pub struct ThemeStyleContent {
#[serde(default, rename = "background.appearance")]
#[serde(rename = "background.appearance")]
pub window_background_appearance: Option<WindowBackgroundContent>,
#[serde(default)]
@@ -380,18 +362,18 @@ pub struct PlayerColorContent {
}
/// Theme name.
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
#[serde(transparent)]
pub struct ThemeName(pub Arc<str>);
/// Icon Theme Name
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
#[serde(transparent)]
pub struct IconThemeName(pub Arc<str>);
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
#[serde(default)]
pub struct ThemeColorsContent {
@@ -925,19 +907,27 @@ pub struct ThemeColorsContent {
pub vim_mode_text: Option<String>,
}
#[skip_serializing_none]
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
#[serde(default)]
pub struct HighlightStyleContent {
pub color: Option<String>,
#[serde(deserialize_with = "treat_error_as_none")]
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "treat_error_as_none"
)]
pub background_color: Option<String>,
#[serde(deserialize_with = "treat_error_as_none")]
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "treat_error_as_none"
)]
pub font_style: Option<FontStyleContent>,
#[serde(deserialize_with = "treat_error_as_none")]
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "treat_error_as_none"
)]
pub font_weight: Option<FontWeightContent>,
}
@@ -959,7 +949,7 @@ where
Ok(T::deserialize(value).ok())
}
#[skip_serializing_none]
#[with_fallible_options]
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
#[serde(default)]
pub struct StatusColorsContent {