use collections::{HashMap, IndexMap};use schemars::JsonSchema;use serde::{Deserialize, Deserializer, Serialize};use serde_json::Value;use settings_macros::{MergeFrom, with_fallible_options};use std::{borrow::Cow, fmt::Display, sync::Arc}; use crate::serialize_f32_with_two_decimal_places; /// OpenType font features as a map of feature tag to value./// This is a content type that mirrors `gpui::FontFeatures` but without the Arc wrapper./// Values can be specified as booleans (true=1, false=0) or integers.#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, MergeFrom)]#[serde(transparent)]pub struct FontFeaturesContent(pub IndexMap<String, u32>); impl FontFeaturesContent { pub fn new() -> Self { Self(IndexMap::default()) }} #[derive(Debug, serde::Deserialize)]#[serde(untagged)]enum FeatureValue { Bool(bool), Number(serde_json::Number),} fn is_valid_feature_tag(tag: &str) -> bool { tag.len() == 4 && tag.chars().all(|c| c.is_ascii_alphanumeric())} impl<'de> Deserialize<'de> for FontFeaturesContent { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { use serde::de::{MapAccess, Visitor}; use std::fmt; struct FontFeaturesVisitor; impl<'de> Visitor<'de> for FontFeaturesVisitor { type Value = FontFeaturesContent; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a map of font features") } fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> where M: MapAccess<'de>, { let mut feature_map = IndexMap::default(); while let Some((key, value)) = access.next_entry::<String, Option<FeatureValue>>()? { if !is_valid_feature_tag(&key) { log::error!("Incorrect font feature tag: {}", key); continue; } if let Some(value) = value { match value { FeatureValue::Bool(enable) => { feature_map.insert(key, if enable { 1 } else { 0 }); } FeatureValue::Number(value) => { if value.is_u64() { feature_map.insert(key, value.as_u64().unwrap() as u32); } else { log::error!( "Incorrect font feature value {} for feature tag {}", value, key ); continue; } } } } } Ok(FontFeaturesContent(feature_map)) } } deserializer.deserialize_map(FontFeaturesVisitor) }} impl JsonSchema for FontFeaturesContent { fn schema_name() -> Cow<'static, str> { "FontFeaturesContent".into() } fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { use schemars::json_schema; json_schema!({ "type": "object", "patternProperties": { "[0-9a-zA-Z]{4}$": { "type": ["boolean", "integer"], "minimum": 0, "multipleOf": 1 } }, "additionalProperties": false }) }} /// Settings for rendering text in UI and text buffers. #[with_fallible_options]#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]pub struct ThemeSettingsContent { /// The default font size for text in the UI. pub ui_font_size: Option<FontSize>, /// The name of a font to use for rendering in the UI. pub ui_font_family: Option<FontFamilyName>, /// The font fallbacks to use for rendering in the UI. #[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. #[schemars(default = "default_font_features")] pub ui_font_features: Option<FontFeaturesContent>, /// The weight of the UI font in CSS units from 100 to 900. #[schemars(default = "default_buffer_font_weight")] pub ui_font_weight: Option<FontWeightContent>, /// The name of a font to use for rendering in text buffers. pub buffer_font_family: Option<FontFamilyName>, /// The font fallbacks to use for rendering in text buffers. #[schemars(extend("uniqueItems" = true))] pub buffer_font_fallbacks: Option<Vec<FontFamilyName>>, /// The default font size for rendering in text buffers. pub buffer_font_size: Option<FontSize>, /// The weight of the editor font in CSS units from 100 to 900. #[schemars(default = "default_buffer_font_weight")] pub buffer_font_weight: Option<FontWeightContent>, /// The buffer's line height. pub buffer_line_height: Option<BufferLineHeight>, /// The OpenType features to enable for rendering in text buffers. #[schemars(default = "default_font_features")] pub buffer_font_features: Option<FontFeaturesContent>, /// The font size for agent responses in the agent panel. Falls back to the UI font size if unset. pub agent_ui_font_size: Option<FontSize>, /// The font size for user messages in the agent panel. pub agent_buffer_font_size: Option<FontSize>, /// The name of the Zed theme to use. pub theme: Option<ThemeSelection>, /// The name of the icon theme to use. pub icon_theme: Option<IconThemeSelection>, /// UNSTABLE: Expect many elements to be broken. /// // Controls the density of the UI. #[serde(rename = "unstable.ui_density")] pub ui_density: Option<UiDensity>, /// How much to fade out unused code. #[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")] pub experimental_theme_overrides: Option<ThemeStyleContent>, /// Overrides per theme /// /// These values will override the ones on the specified theme #[serde(default)] pub theme_overrides: HashMap<String, ThemeStyleContent>,} /// A font size value in pixels, wrapping around `f32` for custom settings UI rendering.#[derive( Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, PartialOrd, derive_more::FromStr,)]#[serde(transparent)]pub struct FontSize(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32); impl Display for FontSize { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:.2}", self.0) }} impl From<f32> for FontSize { fn from(value: f32) -> Self { Self(value) }} #[derive( Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, PartialOrd, derive_more::FromStr,)]#[serde(transparent)]pub struct CodeFade(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32); impl Display for CodeFade { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:.2}", self.0) }} impl From<f32> for CodeFade { fn from(x: f32) -> Self { Self(x) }} fn default_font_features() -> Option<FontFeaturesContent> { Some(FontFeaturesContent::default())} fn default_font_fallbacks() -> Option<Vec<FontFamilyName>> { Some(Vec::new())} fn default_buffer_font_weight() -> Option<FontWeightContent> { Some(FontWeightContent::NORMAL)} /// Represents the selection of a theme, which can be either static or dynamic.#[derive( Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::EnumDiscriminants,)]#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]#[serde(untagged)]pub enum ThemeSelection { /// A static theme selection, represented by a single theme name. Static(ThemeName), /// A dynamic theme selection, which can change based the [ThemeMode]. Dynamic { /// The mode used to determine which theme to use. #[serde(default)] mode: ThemeAppearanceMode, /// The theme to use for light mode. light: ThemeName, /// The theme to use for dark mode. dark: ThemeName, },} pub const DEFAULT_LIGHT_THEME: &'static str = "One Light";pub const DEFAULT_DARK_THEME: &'static str = "One Dark"; impl Default for ThemeSelection { fn default() -> Self { Self::Dynamic { mode: ThemeAppearanceMode::default(), light: ThemeName(DEFAULT_LIGHT_THEME.into()), dark: ThemeName(DEFAULT_DARK_THEME.into()), } }} /// Represents the selection of an icon theme, which can be either static or dynamic.#[derive( Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::EnumDiscriminants,)]#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]#[serde(untagged)]pub enum IconThemeSelection { /// A static icon theme selection, represented by a single icon theme name. Static(IconThemeName), /// A dynamic icon theme selection, which can change based on the [`ThemeMode`]. Dynamic { /// The mode used to determine which theme to use. #[serde(default)] mode: ThemeAppearanceMode, /// The icon theme to use for light mode. light: IconThemeName, /// The icon theme to use for dark mode. dark: IconThemeName, },} /// The mode use to select a theme.////// `Light` and `Dark` will select their respective themes.////// `System` will select the theme based on the system's appearance.#[derive( Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames,)]#[serde(rename_all = "snake_case")]pub enum ThemeAppearanceMode { /// Use the specified `light` theme. Light, /// Use the specified `dark` theme. Dark, /// Use the theme based on the system's appearance. #[default] System,} /// Specifies the density of the UI./// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078)#[derive( Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom,)]#[serde(rename_all = "snake_case")]pub enum UiDensity { /// A denser UI with tighter spacing and smaller elements. #[serde(alias = "compact")] Compact, #[default] #[serde(alias = "default")] /// The default UI density. Default, #[serde(alias = "comfortable")] /// A looser UI with more spacing and larger elements. Comfortable,} impl UiDensity { /// The spacing ratio of a given density. /// TODO: Standardize usage throughout the app or remove pub fn spacing_ratio(self) -> f32 { match self { UiDensity::Compact => 0.75, UiDensity::Default => 1.0, UiDensity::Comfortable => 1.25, } }} /// Font family name.#[with_fallible_options]#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]#[serde(transparent)]pub struct FontFamilyName(pub Arc<str>); impl AsRef<str> for FontFamilyName { fn as_ref(&self) -> &str { &self.0 }} impl From<String> for FontFamilyName { fn from(value: String) -> Self { Self(Arc::from(value)) }} impl From<FontFamilyName> for String { fn from(value: FontFamilyName) -> Self { value.0.to_string() }} /// The buffer's line height.#[derive( Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Default, strum::EnumDiscriminants,)]#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]#[serde(rename_all = "snake_case")]pub enum BufferLineHeight { /// A less dense line height. #[default] Comfortable, /// The default line height. Standard, /// A custom line height, where 1.0 is the font's height. Must be at least 1.0. Custom(#[serde(deserialize_with = "deserialize_line_height")] f32),} fn deserialize_line_height<'de, D>(deserializer: D) -> Result<f32, D::Error>where D: serde::Deserializer<'de>,{ let value = f32::deserialize(deserializer)?; if value < 1.0 { return Err(serde::de::Error::custom( "buffer_line_height.custom must be at least 1.0", )); } Ok(value)} /// The content of a serialized theme.#[with_fallible_options]#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]#[serde(default)]pub struct ThemeStyleContent { #[serde(rename = "background.appearance")] pub window_background_appearance: Option<WindowBackgroundContent>, #[serde(default)] pub accents: Vec<AccentContent>, #[serde(flatten, default)] pub colors: ThemeColorsContent, #[serde(flatten, default)] pub status: StatusColorsContent, #[serde(default)] pub players: Vec<PlayerColorContent>, /// The styles for syntax nodes. #[serde(default)] pub syntax: IndexMap<String, HighlightStyleContent>,} #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]pub struct AccentContent(pub Option<String>); #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]pub struct PlayerColorContent { pub cursor: Option<String>, pub background: Option<String>, pub selection: Option<String>,} /// Theme name.#[with_fallible_options]#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]#[serde(transparent)]pub struct ThemeName(pub Arc<str>); /// Icon Theme Name#[with_fallible_options]#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]#[serde(transparent)]Lines 1–500 of 1428. Load more
use collections::{HashMap, IndexMap}; use schemars::JsonSchema; use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use settings_macros::{MergeFrom, with_fallible_options}; use std::{borrow::Cow, fmt::Display, sync::Arc}; use crate::serialize_f32_with_two_decimal_places; /// OpenType font features as a map of feature tag to value. /// This is a content type that mirrors `gpui::FontFeatures` but without the Arc wrapper. /// Values can be specified as booleans (true=1, false=0) or integers. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, MergeFrom)] #[serde(transparent)] pub struct FontFeaturesContent(pub IndexMap<String, u32>); impl FontFeaturesContent { pub fn new() -> Self { Self(IndexMap::default()) } } #[derive(Debug, serde::Deserialize)] #[serde(untagged)] enum FeatureValue { Bool(bool), Number(serde_json::Number), } fn is_valid_feature_tag(tag: &str) -> bool { tag.len() == 4 && tag.chars().all(|c| c.is_ascii_alphanumeric()) } impl<'de> Deserialize<'de> for FontFeaturesContent { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { use serde::de::{MapAccess, Visitor}; use std::fmt; struct FontFeaturesVisitor; impl<'de> Visitor<'de> for FontFeaturesVisitor { type Value = FontFeaturesContent; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a map of font features") } fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error> where M: MapAccess<'de>, { let mut feature_map = IndexMap::default(); while let Some((key, value)) = access.next_entry::<String, Option<FeatureValue>>()? { if !is_valid_feature_tag(&key) { log::error!("Incorrect font feature tag: {}", key); continue; } if let Some(value) = value { match value { FeatureValue::Bool(enable) => { feature_map.insert(key, if enable { 1 } else { 0 }); } FeatureValue::Number(value) => { if value.is_u64() { feature_map.insert(key, value.as_u64().unwrap() as u32); } else { log::error!( "Incorrect font feature value {} for feature tag {}", value, key ); continue; } } } } } Ok(FontFeaturesContent(feature_map)) } } deserializer.deserialize_map(FontFeaturesVisitor) } } impl JsonSchema for FontFeaturesContent { fn schema_name() -> Cow<'static, str> { "FontFeaturesContent".into() } fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema { use schemars::json_schema; json_schema!({ "type": "object", "patternProperties": { "[0-9a-zA-Z]{4}$": { "type": ["boolean", "integer"], "minimum": 0, "multipleOf": 1 } }, "additionalProperties": false }) } } /// Settings for rendering text in UI and text buffers. #[with_fallible_options] #[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)] pub struct ThemeSettingsContent { /// The default font size for text in the UI. pub ui_font_size: Option<FontSize>, /// The name of a font to use for rendering in the UI. pub ui_font_family: Option<FontFamilyName>, /// The font fallbacks to use for rendering in the UI. #[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. #[schemars(default = "default_font_features")] pub ui_font_features: Option<FontFeaturesContent>, /// The weight of the UI font in CSS units from 100 to 900. #[schemars(default = "default_buffer_font_weight")] pub ui_font_weight: Option<FontWeightContent>, /// The name of a font to use for rendering in text buffers. pub buffer_font_family: Option<FontFamilyName>, /// The font fallbacks to use for rendering in text buffers. #[schemars(extend("uniqueItems" = true))] pub buffer_font_fallbacks: Option<Vec<FontFamilyName>>, /// The default font size for rendering in text buffers. pub buffer_font_size: Option<FontSize>, /// The weight of the editor font in CSS units from 100 to 900. #[schemars(default = "default_buffer_font_weight")] pub buffer_font_weight: Option<FontWeightContent>, /// The buffer's line height. pub buffer_line_height: Option<BufferLineHeight>, /// The OpenType features to enable for rendering in text buffers. #[schemars(default = "default_font_features")] pub buffer_font_features: Option<FontFeaturesContent>, /// The font size for agent responses in the agent panel. Falls back to the UI font size if unset. pub agent_ui_font_size: Option<FontSize>, /// The font size for user messages in the agent panel. pub agent_buffer_font_size: Option<FontSize>, /// The name of the Zed theme to use. pub theme: Option<ThemeSelection>, /// The name of the icon theme to use. pub icon_theme: Option<IconThemeSelection>, /// UNSTABLE: Expect many elements to be broken. /// // Controls the density of the UI. #[serde(rename = "unstable.ui_density")] pub ui_density: Option<UiDensity>, /// How much to fade out unused code. #[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")] pub experimental_theme_overrides: Option<ThemeStyleContent>, /// Overrides per theme /// /// These values will override the ones on the specified theme #[serde(default)] pub theme_overrides: HashMap<String, ThemeStyleContent>, } /// A font size value in pixels, wrapping around `f32` for custom settings UI rendering. #[derive( Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, PartialOrd, derive_more::FromStr, )] #[serde(transparent)] pub struct FontSize(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32); impl Display for FontSize { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:.2}", self.0) } } impl From<f32> for FontSize { fn from(value: f32) -> Self { Self(value) } } #[derive( Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, PartialOrd, derive_more::FromStr, )] #[serde(transparent)] pub struct CodeFade(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32); impl Display for CodeFade { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{:.2}", self.0) } } impl From<f32> for CodeFade { fn from(x: f32) -> Self { Self(x) } } fn default_font_features() -> Option<FontFeaturesContent> { Some(FontFeaturesContent::default()) } fn default_font_fallbacks() -> Option<Vec<FontFamilyName>> { Some(Vec::new()) } fn default_buffer_font_weight() -> Option<FontWeightContent> { Some(FontWeightContent::NORMAL) } /// Represents the selection of a theme, which can be either static or dynamic. #[derive( Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::EnumDiscriminants, )] #[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))] #[serde(untagged)] pub enum ThemeSelection { /// A static theme selection, represented by a single theme name. Static(ThemeName), /// A dynamic theme selection, which can change based the [ThemeMode]. Dynamic { /// The mode used to determine which theme to use. #[serde(default)] mode: ThemeAppearanceMode, /// The theme to use for light mode. light: ThemeName, /// The theme to use for dark mode. dark: ThemeName, }, } pub const DEFAULT_LIGHT_THEME: &'static str = "One Light"; pub const DEFAULT_DARK_THEME: &'static str = "One Dark"; impl Default for ThemeSelection { fn default() -> Self { Self::Dynamic { mode: ThemeAppearanceMode::default(), light: ThemeName(DEFAULT_LIGHT_THEME.into()), dark: ThemeName(DEFAULT_DARK_THEME.into()), } } } /// Represents the selection of an icon theme, which can be either static or dynamic. #[derive( Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq, strum::EnumDiscriminants, )] #[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))] #[serde(untagged)] pub enum IconThemeSelection { /// A static icon theme selection, represented by a single icon theme name. Static(IconThemeName), /// A dynamic icon theme selection, which can change based on the [`ThemeMode`]. Dynamic { /// The mode used to determine which theme to use. #[serde(default)] mode: ThemeAppearanceMode, /// The icon theme to use for light mode. light: IconThemeName, /// The icon theme to use for dark mode. dark: IconThemeName, }, } /// The mode use to select a theme. /// /// `Light` and `Dark` will select their respective themes. /// /// `System` will select the theme based on the system's appearance. #[derive( Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema, MergeFrom, strum::VariantArray, strum::VariantNames, )] #[serde(rename_all = "snake_case")] pub enum ThemeAppearanceMode { /// Use the specified `light` theme. Light, /// Use the specified `dark` theme. Dark, /// Use the theme based on the system's appearance. #[default] System, } /// Specifies the density of the UI. /// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078) #[derive( Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom, )] #[serde(rename_all = "snake_case")] pub enum UiDensity { /// A denser UI with tighter spacing and smaller elements. #[serde(alias = "compact")] Compact, #[default] #[serde(alias = "default")] /// The default UI density. Default, #[serde(alias = "comfortable")] /// A looser UI with more spacing and larger elements. Comfortable, } impl UiDensity { /// The spacing ratio of a given density. /// TODO: Standardize usage throughout the app or remove pub fn spacing_ratio(self) -> f32 { match self { UiDensity::Compact => 0.75, UiDensity::Default => 1.0, UiDensity::Comfortable => 1.25, } } } /// Font family name. #[with_fallible_options] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] #[serde(transparent)] pub struct FontFamilyName(pub Arc<str>); impl AsRef<str> for FontFamilyName { fn as_ref(&self) -> &str { &self.0 } } impl From<String> for FontFamilyName { fn from(value: String) -> Self { Self(Arc::from(value)) } } impl From<FontFamilyName> for String { fn from(value: FontFamilyName) -> Self { value.0.to_string() } } /// The buffer's line height. #[derive( Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, MergeFrom, Default, strum::EnumDiscriminants, )] #[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))] #[serde(rename_all = "snake_case")] pub enum BufferLineHeight { /// A less dense line height. #[default] Comfortable, /// The default line height. Standard, /// A custom line height, where 1.0 is the font's height. Must be at least 1.0. Custom(#[serde(deserialize_with = "deserialize_line_height")] f32), } fn deserialize_line_height<'de, D>(deserializer: D) -> Result<f32, D::Error> where D: serde::Deserializer<'de>, { let value = f32::deserialize(deserializer)?; if value < 1.0 { return Err(serde::de::Error::custom( "buffer_line_height.custom must be at least 1.0", )); } Ok(value) } /// The content of a serialized theme. #[with_fallible_options] #[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] #[serde(default)] pub struct ThemeStyleContent { #[serde(rename = "background.appearance")] pub window_background_appearance: Option<WindowBackgroundContent>, #[serde(default)] pub accents: Vec<AccentContent>, #[serde(flatten, default)] pub colors: ThemeColorsContent, #[serde(flatten, default)] pub status: StatusColorsContent, #[serde(default)] pub players: Vec<PlayerColorContent>, /// The styles for syntax nodes. #[serde(default)] pub syntax: IndexMap<String, HighlightStyleContent>, } #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] pub struct AccentContent(pub Option<String>); #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)] pub struct PlayerColorContent { pub cursor: Option<String>, pub background: Option<String>, pub selection: Option<String>, } /// Theme name. #[with_fallible_options] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] #[serde(transparent)] pub struct ThemeName(pub Arc<str>); /// Icon Theme Name #[with_fallible_options] #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)] #[serde(transparent)]