feat: add JsonSchema to Theme

Sergey Onufrienko created

Change summary

crates/theme/src/theme.rs          | 163 ++++++++++++++++---------------
crates/theme/src/theme_settings.rs |   3 
crates/theme/src/ui.rs             |  11 +
3 files changed, 90 insertions(+), 87 deletions(-)

Detailed changes

crates/theme/src/theme.rs 🔗

@@ -8,6 +8,7 @@ use gpui::{
     fonts::{HighlightStyle, TextStyle},
     platform, AppContext, AssetSource, Border, MouseState,
 };
+use schemars::JsonSchema;
 use serde::{de::DeserializeOwned, Deserialize};
 use serde_json::Value;
 use settings::SettingsStore;
@@ -36,7 +37,7 @@ pub fn init(source: impl AssetSource, cx: &mut AppContext) {
     .detach();
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct Theme {
     #[serde(default)]
     pub meta: ThemeMeta,
@@ -67,7 +68,7 @@ pub struct Theme {
     pub color_scheme: ColorScheme,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct ThemeMeta {
     #[serde(skip_deserializing)]
     pub id: usize,
@@ -75,7 +76,7 @@ pub struct ThemeMeta {
     pub is_light: bool,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct Workspace {
     pub background: Color,
     pub blank_pane: BlankPaneStyle,
@@ -102,7 +103,7 @@ pub struct Workspace {
     pub drop_target_overlay_color: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct BlankPaneStyle {
     pub logo: SvgStyle,
     pub logo_shadow: SvgStyle,
@@ -112,7 +113,7 @@ pub struct BlankPaneStyle {
     pub keyboard_hint_width: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Titlebar {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -137,7 +138,7 @@ pub struct Titlebar {
     pub toggle_contacts_badge: ContainerStyle,
 }
 
-#[derive(Copy, Clone, Deserialize, Default)]
+#[derive(Copy, Clone, Deserialize, Default, JsonSchema)]
 pub struct AvatarStyle {
     #[serde(flatten)]
     pub image: ImageStyle,
@@ -145,14 +146,14 @@ pub struct AvatarStyle {
     pub outer_corner_radius: f32,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct Copilot {
     pub out_link_icon: Interactive<IconStyle>,
     pub modal: ModalStyle,
     pub auth: CopilotAuth,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct CopilotAuth {
     pub content_width: f32,
     pub prompting: CopilotAuthPrompting,
@@ -162,14 +163,14 @@ pub struct CopilotAuth {
     pub header: IconStyle,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct CopilotAuthPrompting {
     pub subheading: ContainedText,
     pub hint: ContainedText,
     pub device_code: DeviceCode,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct DeviceCode {
     pub text: TextStyle,
     pub cta: ButtonStyle,
@@ -179,19 +180,19 @@ pub struct DeviceCode {
     pub right_container: Interactive<ContainerStyle>,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct CopilotAuthNotAuthorized {
     pub subheading: ContainedText,
     pub warning: ContainedText,
 }
 
-#[derive(Deserialize, Default, Clone)]
+#[derive(Deserialize, Default, Clone, JsonSchema)]
 pub struct CopilotAuthAuthorized {
     pub subheading: ContainedText,
     pub hint: ContainedText,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ContactsPopover {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -199,7 +200,7 @@ pub struct ContactsPopover {
     pub width: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ContactList {
     pub user_query_editor: FieldEditor,
     pub user_query_editor_height: f32,
@@ -221,7 +222,7 @@ pub struct ContactList {
     pub calling_indicator: ContainedText,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ProjectRow {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -229,13 +230,13 @@ pub struct ProjectRow {
     pub name: ContainedText,
 }
 
-#[derive(Deserialize, Default, Clone, Copy)]
+#[derive(Deserialize, Default, Clone, Copy, JsonSchema)]
 pub struct TreeBranch {
     pub width: f32,
     pub color: Color,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ContactFinder {
     pub picker: Picker,
     pub row_height: f32,
@@ -245,7 +246,7 @@ pub struct ContactFinder {
     pub disabled_contact_button: IconButton,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct LspLogMenu {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -255,7 +256,7 @@ pub struct LspLogMenu {
     pub row_height: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct TabBar {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -283,13 +284,13 @@ impl TabBar {
     }
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct TabStyles {
     pub active_tab: Tab,
     pub inactive_tab: Tab,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct AvatarRibbon {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -297,7 +298,7 @@ pub struct AvatarRibbon {
     pub height: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct OfflineIcon {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -305,7 +306,7 @@ pub struct OfflineIcon {
     pub color: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Tab {
     pub height: f32,
     #[serde(flatten)]
@@ -322,7 +323,7 @@ pub struct Tab {
     pub icon_conflict: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Toolbar {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -331,14 +332,14 @@ pub struct Toolbar {
     pub nav_button: Interactive<IconButton>,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Notifications {
     #[serde(flatten)]
     pub container: ContainerStyle,
     pub width: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Search {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -355,7 +356,7 @@ pub struct Search {
     pub dismiss_button: Interactive<IconButton>,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct FindEditor {
     #[serde(flatten)]
     pub input: FieldEditor,
@@ -363,7 +364,7 @@ pub struct FindEditor {
     pub max_width: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct StatusBar {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -379,7 +380,7 @@ pub struct StatusBar {
     pub diagnostic_message: Interactive<ContainedText>,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct StatusBarPanelButtons {
     pub group_left: ContainerStyle,
     pub group_bottom: ContainerStyle,
@@ -387,7 +388,7 @@ pub struct StatusBarPanelButtons {
     pub button: Interactive<PanelButton>,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct StatusBarDiagnosticSummary {
     pub container_ok: ContainerStyle,
     pub container_warning: ContainerStyle,
@@ -402,7 +403,7 @@ pub struct StatusBarDiagnosticSummary {
     pub summary_spacing: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct StatusBarLspStatus {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -413,14 +414,14 @@ pub struct StatusBarLspStatus {
     pub message: TextStyle,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct Dock {
     pub left: ContainerStyle,
     pub bottom: ContainerStyle,
     pub right: ContainerStyle,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct PanelButton {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -429,7 +430,7 @@ pub struct PanelButton {
     pub label: ContainedText,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ProjectPanel {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -442,7 +443,7 @@ pub struct ProjectPanel {
     pub open_project_button: Interactive<ContainedText>,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct ProjectPanelEntry {
     pub height: f32,
     #[serde(flatten)]
@@ -454,19 +455,19 @@ pub struct ProjectPanelEntry {
     pub status: EntryStatus,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct EntryStatus {
     pub git: GitProjectStatus,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct GitProjectStatus {
     pub modified: Color,
     pub inserted: Color,
     pub conflict: Color,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct ContextMenu {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -475,7 +476,7 @@ pub struct ContextMenu {
     pub separator: ContainerStyle,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct ContextMenuItem {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -485,13 +486,13 @@ pub struct ContextMenuItem {
     pub icon_spacing: f32,
 }
 
-#[derive(Debug, Deserialize, Default)]
+#[derive(Debug, Deserialize, Default, JsonSchema)]
 pub struct CommandPalette {
     pub key: Interactive<ContainedLabel>,
     pub keystroke_spacing: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct InviteLink {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -500,7 +501,7 @@ pub struct InviteLink {
     pub icon: Icon,
 }
 
-#[derive(Deserialize, Clone, Copy, Default)]
+#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
 pub struct Icon {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -508,7 +509,7 @@ pub struct Icon {
     pub width: f32,
 }
 
-#[derive(Deserialize, Clone, Copy, Default)]
+#[derive(Deserialize, Clone, Copy, Default, JsonSchema)]
 pub struct IconButton {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -517,7 +518,7 @@ pub struct IconButton {
     pub button_width: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ChatMessage {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -526,7 +527,7 @@ pub struct ChatMessage {
     pub timestamp: ContainedText,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ChannelSelect {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -538,7 +539,7 @@ pub struct ChannelSelect {
     pub menu: ContainerStyle,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ChannelName {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -546,7 +547,7 @@ pub struct ChannelName {
     pub name: TextStyle,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Picker {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -557,7 +558,7 @@ pub struct Picker {
     pub item: Interactive<ContainedLabel>,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct ContainedText {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -565,7 +566,7 @@ pub struct ContainedText {
     pub text: TextStyle,
 }
 
-#[derive(Clone, Debug, Deserialize, Default)]
+#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]
 pub struct ContainedLabel {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -573,7 +574,7 @@ pub struct ContainedLabel {
     pub label: LabelStyle,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct ProjectDiagnostics {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -583,7 +584,7 @@ pub struct ProjectDiagnostics {
     pub tab_summary_spacing: f32,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ContactNotification {
     pub header_avatar: ImageStyle,
     pub header_message: ContainedText,
@@ -593,21 +594,21 @@ pub struct ContactNotification {
     pub dismiss_button: Interactive<IconButton>,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct UpdateNotification {
     pub message: ContainedText,
     pub action_message: Interactive<ContainedText>,
     pub dismiss_button: Interactive<IconButton>,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct MessageNotification {
     pub message: ContainedText,
     pub action_message: Interactive<ContainedText>,
     pub dismiss_button: Interactive<IconButton>,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct ProjectSharedNotification {
     pub window_height: f32,
     pub window_width: f32,
@@ -624,7 +625,7 @@ pub struct ProjectSharedNotification {
     pub dismiss_button: ContainedText,
 }
 
-#[derive(Deserialize, Default)]
+#[derive(Deserialize, Default, JsonSchema)]
 pub struct IncomingCallNotification {
     pub window_height: f32,
     pub window_width: f32,
@@ -641,7 +642,7 @@ pub struct IncomingCallNotification {
     pub decline_button: ContainedText,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Editor {
     pub text_color: Color,
     #[serde(default)]
@@ -682,7 +683,7 @@ pub struct Editor {
     pub whitespace: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Scrollbar {
     pub track: ContainerStyle,
     pub thumb: ContainerStyle,
@@ -691,14 +692,14 @@ pub struct Scrollbar {
     pub git: GitDiffColors,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct GitDiffColors {
     pub inserted: Color,
     pub modified: Color,
     pub deleted: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct DiagnosticPathHeader {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -707,7 +708,7 @@ pub struct DiagnosticPathHeader {
     pub text_scale_factor: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct DiagnosticHeader {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -718,7 +719,7 @@ pub struct DiagnosticHeader {
     pub icon_width_factor: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct DiagnosticStyle {
     pub message: LabelStyle,
     #[serde(default)]
@@ -726,7 +727,7 @@ pub struct DiagnosticStyle {
     pub text_scale_factor: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct AutocompleteStyle {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -736,13 +737,13 @@ pub struct AutocompleteStyle {
     pub match_highlight: HighlightStyle,
 }
 
-#[derive(Clone, Copy, Default, Deserialize)]
+#[derive(Clone, Copy, Default, Deserialize, JsonSchema)]
 pub struct SelectionStyle {
     pub cursor: Color,
     pub selection: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct FieldEditor {
     #[serde(flatten)]
     pub container: ContainerStyle,
@@ -752,19 +753,19 @@ pub struct FieldEditor {
     pub selection: SelectionStyle,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct InteractiveColor {
     pub color: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct CodeActions {
     #[serde(default)]
     pub indicator: Interactive<InteractiveColor>,
     pub vertical_scale: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Folds {
     pub indicator: Interactive<InteractiveColor>,
     pub ellipses: FoldEllipses,
@@ -774,14 +775,14 @@ pub struct Folds {
     pub foldable_icon: String,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct FoldEllipses {
     pub text_color: Color,
     pub background: Interactive<InteractiveColor>,
     pub corner_radius_factor: f32,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct DiffStyle {
     pub inserted: Color,
     pub modified: Color,
@@ -791,7 +792,7 @@ pub struct DiffStyle {
     pub corner_radius: f32,
 }
 
-#[derive(Debug, Default, Clone, Copy)]
+#[derive(Debug, Default, Clone, Copy, JsonSchema)]
 pub struct Interactive<T> {
     pub default: T,
     pub hover: Option<T>,
@@ -934,7 +935,7 @@ impl<'de> Deserialize<'de> for SyntaxTheme {
     }
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct HoverPopover {
     pub container: ContainerStyle,
     pub info_container: ContainerStyle,
@@ -946,7 +947,7 @@ pub struct HoverPopover {
     pub highlight: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct TerminalStyle {
     pub black: Color,
     pub red: Color,
@@ -980,7 +981,7 @@ pub struct TerminalStyle {
     pub dim_foreground: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct AssistantStyle {
     pub container: ContainerStyle,
     pub header: ContainerStyle,
@@ -997,7 +998,7 @@ pub struct AssistantStyle {
     pub api_key_prompt: ContainedText,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct FeedbackStyle {
     pub submit_button: Interactive<ContainedText>,
     pub button_margin: f32,
@@ -1006,7 +1007,7 @@ pub struct FeedbackStyle {
     pub link_text_hover: ContainedText,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct WelcomeStyle {
     pub page_width: f32,
     pub logo: SvgStyle,
@@ -1020,7 +1021,7 @@ pub struct WelcomeStyle {
     pub checkbox_group: ContainerStyle,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct ColorScheme {
     pub name: String,
     pub is_light: bool,
@@ -1035,13 +1036,13 @@ pub struct ColorScheme {
     pub players: Vec<Player>,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Player {
     pub cursor: Color,
     pub selection: Color,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct RampSet {
     pub neutral: Vec<Color>,
     pub red: Vec<Color>,
@@ -1054,7 +1055,7 @@ pub struct RampSet {
     pub magenta: Vec<Color>,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Layer {
     pub base: StyleSet,
     pub variant: StyleSet,
@@ -1065,7 +1066,7 @@ pub struct Layer {
     pub negative: StyleSet,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct StyleSet {
     pub default: Style,
     pub active: Style,
@@ -1075,7 +1076,7 @@ pub struct StyleSet {
     pub inverted: Style,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Style {
     pub background: Color,
     pub border: Color,

crates/theme/src/theme_settings.rs 🔗

@@ -14,12 +14,13 @@ use util::ResultExt as _;
 
 const MIN_FONT_SIZE: f32 = 6.0;
 
-#[derive(Clone)]
+#[derive(Clone, JsonSchema)]
 pub struct ThemeSettings {
     pub buffer_font_family_name: String,
     pub buffer_font_features: fonts::Features,
     pub buffer_font_family: FamilyId,
     pub(crate) buffer_font_size: f32,
+    #[serde(skip)]
     pub theme: Arc<Theme>,
 }
 

crates/theme/src/ui.rs 🔗

@@ -13,11 +13,12 @@ use gpui::{
     scene::MouseClick,
     Action, Element, EventContext, MouseState, View, ViewContext,
 };
+use schemars::JsonSchema;
 use serde::Deserialize;
 
 use crate::{ContainedText, Interactive};
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct CheckboxStyle {
     pub icon: SvgStyle,
     pub label: ContainedText,
@@ -93,14 +94,14 @@ where
     .with_cursor_style(platform::CursorStyle::PointingHand)
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct SvgStyle {
     pub color: Color,
     pub asset: String,
     pub dimensions: Dimensions,
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct Dimensions {
     pub width: f32,
     pub height: f32,
@@ -120,7 +121,7 @@ pub fn svg<V: View>(style: &SvgStyle) -> ConstrainedBox<V> {
         .with_height(style.dimensions.height)
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct IconStyle {
     icon: SvgStyle,
     container: ContainerStyle,
@@ -182,7 +183,7 @@ where
     .with_cursor_style(platform::CursorStyle::PointingHand)
 }
 
-#[derive(Clone, Deserialize, Default)]
+#[derive(Clone, Deserialize, Default, JsonSchema)]
 pub struct ModalStyle {
     close_icon: Interactive<IconStyle>,
     container: ContainerStyle,