schema.rs

  1#![allow(missing_docs)]
  2
  3use anyhow::Result;
  4use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla, WindowBackgroundAppearance};
  5use indexmap::IndexMap;
  6use palette::FromColor;
  7use schemars::{JsonSchema, JsonSchema_repr};
  8use serde::{Deserialize, Deserializer, Serialize};
  9use serde_json::Value;
 10use serde_repr::{Deserialize_repr, Serialize_repr};
 11
 12use crate::{StatusColorsRefinement, ThemeColorsRefinement};
 13
 14fn ensure_non_opaque(color: Hsla) -> Hsla {
 15    const MAXIMUM_OPACITY: f32 = 0.7;
 16    if color.a <= MAXIMUM_OPACITY {
 17        color
 18    } else {
 19        Hsla {
 20            a: MAXIMUM_OPACITY,
 21            ..color
 22        }
 23    }
 24}
 25
 26fn ensure_opaque(color: Hsla) -> Hsla {
 27    Hsla { a: 1.0, ..color }
 28}
 29
 30#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
 31#[serde(rename_all = "snake_case")]
 32pub enum AppearanceContent {
 33    Light,
 34    Dark,
 35}
 36
 37/// The background appearance of the window.
 38#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
 39#[serde(rename_all = "snake_case")]
 40pub enum WindowBackgroundContent {
 41    Opaque,
 42    Transparent,
 43    Blurred,
 44}
 45
 46impl From<WindowBackgroundContent> for WindowBackgroundAppearance {
 47    fn from(value: WindowBackgroundContent) -> Self {
 48        match value {
 49            WindowBackgroundContent::Opaque => WindowBackgroundAppearance::Opaque,
 50            WindowBackgroundContent::Transparent => WindowBackgroundAppearance::Transparent,
 51            WindowBackgroundContent::Blurred => WindowBackgroundAppearance::Blurred,
 52        }
 53    }
 54}
 55
 56/// The content of a serialized theme family.
 57#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
 58pub struct ThemeFamilyContent {
 59    pub name: String,
 60    pub author: String,
 61    pub themes: Vec<ThemeContent>,
 62}
 63
 64/// The content of a serialized theme.
 65#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
 66pub struct ThemeContent {
 67    pub name: String,
 68    pub appearance: AppearanceContent,
 69    pub style: settings::ThemeStyleContent,
 70}
 71
 72/// The content of a serialized theme.
 73#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
 74#[serde(default)]
 75pub struct ThemeStyleContent {
 76    #[serde(default, rename = "background.appearance")]
 77    pub window_background_appearance: Option<WindowBackgroundContent>,
 78
 79    #[serde(default)]
 80    pub accents: Vec<AccentContent>,
 81
 82    #[serde(flatten, default)]
 83    pub colors: settings::ThemeColorsContent,
 84
 85    #[serde(flatten, default)]
 86    pub status: settings::StatusColorsContent,
 87
 88    #[serde(default)]
 89    pub players: Vec<PlayerColorContent>,
 90
 91    /// The styles for syntax nodes.
 92    #[serde(default)]
 93    pub syntax: IndexMap<String, settings::HighlightStyleContent>,
 94}
 95
 96/// Returns the syntax style overrides in the [`ThemeContent`].
 97pub fn syntax_overrides(this: &settings::ThemeStyleContent) -> Vec<(String, HighlightStyle)> {
 98    this.syntax
 99        .iter()
100        .map(|(key, style)| {
101            (
102                key.clone(),
103                HighlightStyle {
104                    color: style
105                        .color
106                        .as_ref()
107                        .and_then(|color| try_parse_color(color).ok()),
108                    background_color: style
109                        .background_color
110                        .as_ref()
111                        .and_then(|color| try_parse_color(color).ok()),
112                    font_style: style.font_style.map(FontStyle::from),
113                    font_weight: style.font_weight.map(FontWeight::from),
114                    ..Default::default()
115                },
116            )
117        })
118        .collect()
119}
120
121pub fn status_colors_refinement(colors: &settings::StatusColorsContent) -> StatusColorsRefinement {
122    StatusColorsRefinement {
123        conflict: colors
124            .conflict
125            .as_ref()
126            .and_then(|color| try_parse_color(color).ok()),
127        conflict_background: colors
128            .conflict_background
129            .as_ref()
130            .and_then(|color| try_parse_color(color).ok()),
131        conflict_border: colors
132            .conflict_border
133            .as_ref()
134            .and_then(|color| try_parse_color(color).ok()),
135        created: colors
136            .created
137            .as_ref()
138            .and_then(|color| try_parse_color(color).ok()),
139        created_background: colors
140            .created_background
141            .as_ref()
142            .and_then(|color| try_parse_color(color).ok()),
143        created_border: colors
144            .created_border
145            .as_ref()
146            .and_then(|color| try_parse_color(color).ok()),
147        deleted: colors
148            .deleted
149            .as_ref()
150            .and_then(|color| try_parse_color(color).ok()),
151        deleted_background: colors
152            .deleted_background
153            .as_ref()
154            .and_then(|color| try_parse_color(color).ok()),
155        deleted_border: colors
156            .deleted_border
157            .as_ref()
158            .and_then(|color| try_parse_color(color).ok()),
159        error: colors
160            .error
161            .as_ref()
162            .and_then(|color| try_parse_color(color).ok()),
163        error_background: colors
164            .error_background
165            .as_ref()
166            .and_then(|color| try_parse_color(color).ok()),
167        error_border: colors
168            .error_border
169            .as_ref()
170            .and_then(|color| try_parse_color(color).ok()),
171        hidden: colors
172            .hidden
173            .as_ref()
174            .and_then(|color| try_parse_color(color).ok()),
175        hidden_background: colors
176            .hidden_background
177            .as_ref()
178            .and_then(|color| try_parse_color(color).ok()),
179        hidden_border: colors
180            .hidden_border
181            .as_ref()
182            .and_then(|color| try_parse_color(color).ok()),
183        hint: colors
184            .hint
185            .as_ref()
186            .and_then(|color| try_parse_color(color).ok()),
187        hint_background: colors
188            .hint_background
189            .as_ref()
190            .and_then(|color| try_parse_color(color).ok()),
191        hint_border: colors
192            .hint_border
193            .as_ref()
194            .and_then(|color| try_parse_color(color).ok()),
195        ignored: colors
196            .ignored
197            .as_ref()
198            .and_then(|color| try_parse_color(color).ok()),
199        ignored_background: colors
200            .ignored_background
201            .as_ref()
202            .and_then(|color| try_parse_color(color).ok()),
203        ignored_border: colors
204            .ignored_border
205            .as_ref()
206            .and_then(|color| try_parse_color(color).ok()),
207        info: colors
208            .info
209            .as_ref()
210            .and_then(|color| try_parse_color(color).ok()),
211        info_background: colors
212            .info_background
213            .as_ref()
214            .and_then(|color| try_parse_color(color).ok()),
215        info_border: colors
216            .info_border
217            .as_ref()
218            .and_then(|color| try_parse_color(color).ok()),
219        modified: colors
220            .modified
221            .as_ref()
222            .and_then(|color| try_parse_color(color).ok()),
223        modified_background: colors
224            .modified_background
225            .as_ref()
226            .and_then(|color| try_parse_color(color).ok()),
227        modified_border: colors
228            .modified_border
229            .as_ref()
230            .and_then(|color| try_parse_color(color).ok()),
231        predictive: colors
232            .predictive
233            .as_ref()
234            .and_then(|color| try_parse_color(color).ok()),
235        predictive_background: colors
236            .predictive_background
237            .as_ref()
238            .and_then(|color| try_parse_color(color).ok()),
239        predictive_border: colors
240            .predictive_border
241            .as_ref()
242            .and_then(|color| try_parse_color(color).ok()),
243        renamed: colors
244            .renamed
245            .as_ref()
246            .and_then(|color| try_parse_color(color).ok()),
247        renamed_background: colors
248            .renamed_background
249            .as_ref()
250            .and_then(|color| try_parse_color(color).ok()),
251        renamed_border: colors
252            .renamed_border
253            .as_ref()
254            .and_then(|color| try_parse_color(color).ok()),
255        success: colors
256            .success
257            .as_ref()
258            .and_then(|color| try_parse_color(color).ok()),
259        success_background: colors
260            .success_background
261            .as_ref()
262            .and_then(|color| try_parse_color(color).ok()),
263        success_border: colors
264            .success_border
265            .as_ref()
266            .and_then(|color| try_parse_color(color).ok()),
267        unreachable: colors
268            .unreachable
269            .as_ref()
270            .and_then(|color| try_parse_color(color).ok()),
271        unreachable_background: colors
272            .unreachable_background
273            .as_ref()
274            .and_then(|color| try_parse_color(color).ok()),
275        unreachable_border: colors
276            .unreachable_border
277            .as_ref()
278            .and_then(|color| try_parse_color(color).ok()),
279        warning: colors
280            .warning
281            .as_ref()
282            .and_then(|color| try_parse_color(color).ok()),
283        warning_background: colors
284            .warning_background
285            .as_ref()
286            .and_then(|color| try_parse_color(color).ok()),
287        warning_border: colors
288            .warning_border
289            .as_ref()
290            .and_then(|color| try_parse_color(color).ok()),
291    }
292}
293
294#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
295pub struct AccentContent(pub Option<String>);
296
297#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
298pub struct PlayerColorContent {
299    pub cursor: Option<String>,
300    pub background: Option<String>,
301    pub selection: Option<String>,
302}
303
304#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, JsonSchema_repr, PartialEq)]
305#[repr(u16)]
306pub enum FontWeightContent {
307    Thin = 100,
308    ExtraLight = 200,
309    Light = 300,
310    Normal = 400,
311    Medium = 500,
312    Semibold = 600,
313    Bold = 700,
314    ExtraBold = 800,
315    Black = 900,
316}
317
318pub fn theme_colors_refinement(
319    this: &settings::ThemeColorsContent,
320    status_colors: &StatusColorsRefinement,
321) -> ThemeColorsRefinement {
322    let border = this
323        .border
324        .as_ref()
325        .and_then(|color| try_parse_color(color).ok());
326    let editor_document_highlight_read_background = this
327        .editor_document_highlight_read_background
328        .as_ref()
329        .and_then(|color| try_parse_color(color).ok());
330    let scrollbar_thumb_background = this
331        .scrollbar_thumb_background
332        .as_ref()
333        .and_then(|color| try_parse_color(color).ok())
334        .or_else(|| {
335            this.deprecated_scrollbar_thumb_background
336                .as_ref()
337                .and_then(|color| try_parse_color(color).ok())
338        });
339    let scrollbar_thumb_hover_background = this
340        .scrollbar_thumb_hover_background
341        .as_ref()
342        .and_then(|color| try_parse_color(color).ok());
343    let scrollbar_thumb_active_background = this
344        .scrollbar_thumb_active_background
345        .as_ref()
346        .and_then(|color| try_parse_color(color).ok())
347        .or(scrollbar_thumb_background);
348    let scrollbar_thumb_border = this
349        .scrollbar_thumb_border
350        .as_ref()
351        .and_then(|color| try_parse_color(color).ok());
352    let element_hover = this
353        .element_hover
354        .as_ref()
355        .and_then(|color| try_parse_color(color).ok());
356    let panel_background = this
357        .panel_background
358        .as_ref()
359        .and_then(|color| try_parse_color(color).ok());
360    ThemeColorsRefinement {
361        border,
362        border_variant: this
363            .border_variant
364            .as_ref()
365            .and_then(|color| try_parse_color(color).ok()),
366        border_focused: this
367            .border_focused
368            .as_ref()
369            .and_then(|color| try_parse_color(color).ok()),
370        border_selected: this
371            .border_selected
372            .as_ref()
373            .and_then(|color| try_parse_color(color).ok()),
374        border_transparent: this
375            .border_transparent
376            .as_ref()
377            .and_then(|color| try_parse_color(color).ok()),
378        border_disabled: this
379            .border_disabled
380            .as_ref()
381            .and_then(|color| try_parse_color(color).ok()),
382        elevated_surface_background: this
383            .elevated_surface_background
384            .as_ref()
385            .and_then(|color| try_parse_color(color).ok()),
386        surface_background: this
387            .surface_background
388            .as_ref()
389            .and_then(|color| try_parse_color(color).ok()),
390        background: this
391            .background
392            .as_ref()
393            .and_then(|color| try_parse_color(color).ok()),
394        element_background: this
395            .element_background
396            .as_ref()
397            .and_then(|color| try_parse_color(color).ok()),
398        element_hover,
399        element_active: this
400            .element_active
401            .as_ref()
402            .and_then(|color| try_parse_color(color).ok()),
403        element_selected: this
404            .element_selected
405            .as_ref()
406            .and_then(|color| try_parse_color(color).ok()),
407        element_disabled: this
408            .element_disabled
409            .as_ref()
410            .and_then(|color| try_parse_color(color).ok()),
411        element_selection_background: this
412            .element_selection_background
413            .as_ref()
414            .and_then(|color| try_parse_color(color).ok()),
415        drop_target_background: this
416            .drop_target_background
417            .as_ref()
418            .and_then(|color| try_parse_color(color).ok()),
419        drop_target_border: this
420            .drop_target_border
421            .as_ref()
422            .and_then(|color| try_parse_color(color).ok()),
423        ghost_element_background: this
424            .ghost_element_background
425            .as_ref()
426            .and_then(|color| try_parse_color(color).ok()),
427        ghost_element_hover: this
428            .ghost_element_hover
429            .as_ref()
430            .and_then(|color| try_parse_color(color).ok()),
431        ghost_element_active: this
432            .ghost_element_active
433            .as_ref()
434            .and_then(|color| try_parse_color(color).ok()),
435        ghost_element_selected: this
436            .ghost_element_selected
437            .as_ref()
438            .and_then(|color| try_parse_color(color).ok()),
439        ghost_element_disabled: this
440            .ghost_element_disabled
441            .as_ref()
442            .and_then(|color| try_parse_color(color).ok()),
443        text: this
444            .text
445            .as_ref()
446            .and_then(|color| try_parse_color(color).ok()),
447        text_muted: this
448            .text_muted
449            .as_ref()
450            .and_then(|color| try_parse_color(color).ok()),
451        text_placeholder: this
452            .text_placeholder
453            .as_ref()
454            .and_then(|color| try_parse_color(color).ok()),
455        text_disabled: this
456            .text_disabled
457            .as_ref()
458            .and_then(|color| try_parse_color(color).ok()),
459        text_accent: this
460            .text_accent
461            .as_ref()
462            .and_then(|color| try_parse_color(color).ok()),
463        icon: this
464            .icon
465            .as_ref()
466            .and_then(|color| try_parse_color(color).ok()),
467        icon_muted: this
468            .icon_muted
469            .as_ref()
470            .and_then(|color| try_parse_color(color).ok()),
471        icon_disabled: this
472            .icon_disabled
473            .as_ref()
474            .and_then(|color| try_parse_color(color).ok()),
475        icon_placeholder: this
476            .icon_placeholder
477            .as_ref()
478            .and_then(|color| try_parse_color(color).ok()),
479        icon_accent: this
480            .icon_accent
481            .as_ref()
482            .and_then(|color| try_parse_color(color).ok()),
483        debugger_accent: this
484            .debugger_accent
485            .as_ref()
486            .and_then(|color| try_parse_color(color).ok()),
487        status_bar_background: this
488            .status_bar_background
489            .as_ref()
490            .and_then(|color| try_parse_color(color).ok()),
491        title_bar_background: this
492            .title_bar_background
493            .as_ref()
494            .and_then(|color| try_parse_color(color).ok()),
495        title_bar_inactive_background: this
496            .title_bar_inactive_background
497            .as_ref()
498            .and_then(|color| try_parse_color(color).ok()),
499        toolbar_background: this
500            .toolbar_background
501            .as_ref()
502            .and_then(|color| try_parse_color(color).ok()),
503        tab_bar_background: this
504            .tab_bar_background
505            .as_ref()
506            .and_then(|color| try_parse_color(color).ok()),
507        tab_inactive_background: this
508            .tab_inactive_background
509            .as_ref()
510            .and_then(|color| try_parse_color(color).ok()),
511        tab_active_background: this
512            .tab_active_background
513            .as_ref()
514            .and_then(|color| try_parse_color(color).ok()),
515        search_match_background: this
516            .search_match_background
517            .as_ref()
518            .and_then(|color| try_parse_color(color).ok()),
519        panel_background,
520        panel_focused_border: this
521            .panel_focused_border
522            .as_ref()
523            .and_then(|color| try_parse_color(color).ok()),
524        panel_indent_guide: this
525            .panel_indent_guide
526            .as_ref()
527            .and_then(|color| try_parse_color(color).ok()),
528        panel_indent_guide_hover: this
529            .panel_indent_guide_hover
530            .as_ref()
531            .and_then(|color| try_parse_color(color).ok()),
532        panel_indent_guide_active: this
533            .panel_indent_guide_active
534            .as_ref()
535            .and_then(|color| try_parse_color(color).ok()),
536        panel_overlay_background: this
537            .panel_overlay_background
538            .as_ref()
539            .and_then(|color| try_parse_color(color).ok())
540            .or(panel_background.map(ensure_opaque)),
541        panel_overlay_hover: this
542            .panel_overlay_hover
543            .as_ref()
544            .and_then(|color| try_parse_color(color).ok())
545            .or(panel_background
546                .zip(element_hover)
547                .map(|(panel_bg, hover_bg)| panel_bg.blend(hover_bg))
548                .map(ensure_opaque)),
549        pane_focused_border: this
550            .pane_focused_border
551            .as_ref()
552            .and_then(|color| try_parse_color(color).ok()),
553        pane_group_border: this
554            .pane_group_border
555            .as_ref()
556            .and_then(|color| try_parse_color(color).ok())
557            .or(border),
558        scrollbar_thumb_background,
559        scrollbar_thumb_hover_background,
560        scrollbar_thumb_active_background,
561        scrollbar_thumb_border,
562        scrollbar_track_background: this
563            .scrollbar_track_background
564            .as_ref()
565            .and_then(|color| try_parse_color(color).ok()),
566        scrollbar_track_border: this
567            .scrollbar_track_border
568            .as_ref()
569            .and_then(|color| try_parse_color(color).ok()),
570        minimap_thumb_background: this
571            .minimap_thumb_background
572            .as_ref()
573            .and_then(|color| try_parse_color(color).ok())
574            .or(scrollbar_thumb_background.map(ensure_non_opaque)),
575        minimap_thumb_hover_background: this
576            .minimap_thumb_hover_background
577            .as_ref()
578            .and_then(|color| try_parse_color(color).ok())
579            .or(scrollbar_thumb_hover_background.map(ensure_non_opaque)),
580        minimap_thumb_active_background: this
581            .minimap_thumb_active_background
582            .as_ref()
583            .and_then(|color| try_parse_color(color).ok())
584            .or(scrollbar_thumb_active_background.map(ensure_non_opaque)),
585        minimap_thumb_border: this
586            .minimap_thumb_border
587            .as_ref()
588            .and_then(|color| try_parse_color(color).ok())
589            .or(scrollbar_thumb_border),
590        editor_foreground: this
591            .editor_foreground
592            .as_ref()
593            .and_then(|color| try_parse_color(color).ok()),
594        editor_background: this
595            .editor_background
596            .as_ref()
597            .and_then(|color| try_parse_color(color).ok()),
598        editor_gutter_background: this
599            .editor_gutter_background
600            .as_ref()
601            .and_then(|color| try_parse_color(color).ok()),
602        editor_subheader_background: this
603            .editor_subheader_background
604            .as_ref()
605            .and_then(|color| try_parse_color(color).ok()),
606        editor_active_line_background: this
607            .editor_active_line_background
608            .as_ref()
609            .and_then(|color| try_parse_color(color).ok()),
610        editor_highlighted_line_background: this
611            .editor_highlighted_line_background
612            .as_ref()
613            .and_then(|color| try_parse_color(color).ok()),
614        editor_debugger_active_line_background: this
615            .editor_debugger_active_line_background
616            .as_ref()
617            .and_then(|color| try_parse_color(color).ok()),
618        editor_line_number: this
619            .editor_line_number
620            .as_ref()
621            .and_then(|color| try_parse_color(color).ok()),
622        editor_hover_line_number: this
623            .editor_hover_line_number
624            .as_ref()
625            .and_then(|color| try_parse_color(color).ok()),
626        editor_active_line_number: this
627            .editor_active_line_number
628            .as_ref()
629            .and_then(|color| try_parse_color(color).ok()),
630        editor_invisible: this
631            .editor_invisible
632            .as_ref()
633            .and_then(|color| try_parse_color(color).ok()),
634        editor_wrap_guide: this
635            .editor_wrap_guide
636            .as_ref()
637            .and_then(|color| try_parse_color(color).ok()),
638        editor_active_wrap_guide: this
639            .editor_active_wrap_guide
640            .as_ref()
641            .and_then(|color| try_parse_color(color).ok()),
642        editor_indent_guide: this
643            .editor_indent_guide
644            .as_ref()
645            .and_then(|color| try_parse_color(color).ok()),
646        editor_indent_guide_active: this
647            .editor_indent_guide_active
648            .as_ref()
649            .and_then(|color| try_parse_color(color).ok()),
650        editor_document_highlight_read_background,
651        editor_document_highlight_write_background: this
652            .editor_document_highlight_write_background
653            .as_ref()
654            .and_then(|color| try_parse_color(color).ok()),
655        editor_document_highlight_bracket_background: this
656            .editor_document_highlight_bracket_background
657            .as_ref()
658            .and_then(|color| try_parse_color(color).ok())
659            // Fall back to `editor.document_highlight.read_background`, for backwards compatibility.
660            .or(editor_document_highlight_read_background),
661        terminal_background: this
662            .terminal_background
663            .as_ref()
664            .and_then(|color| try_parse_color(color).ok()),
665        terminal_ansi_background: this
666            .terminal_ansi_background
667            .as_ref()
668            .and_then(|color| try_parse_color(color).ok()),
669        terminal_foreground: this
670            .terminal_foreground
671            .as_ref()
672            .and_then(|color| try_parse_color(color).ok()),
673        terminal_bright_foreground: this
674            .terminal_bright_foreground
675            .as_ref()
676            .and_then(|color| try_parse_color(color).ok()),
677        terminal_dim_foreground: this
678            .terminal_dim_foreground
679            .as_ref()
680            .and_then(|color| try_parse_color(color).ok()),
681        terminal_ansi_black: this
682            .terminal_ansi_black
683            .as_ref()
684            .and_then(|color| try_parse_color(color).ok()),
685        terminal_ansi_bright_black: this
686            .terminal_ansi_bright_black
687            .as_ref()
688            .and_then(|color| try_parse_color(color).ok()),
689        terminal_ansi_dim_black: this
690            .terminal_ansi_dim_black
691            .as_ref()
692            .and_then(|color| try_parse_color(color).ok()),
693        terminal_ansi_red: this
694            .terminal_ansi_red
695            .as_ref()
696            .and_then(|color| try_parse_color(color).ok()),
697        terminal_ansi_bright_red: this
698            .terminal_ansi_bright_red
699            .as_ref()
700            .and_then(|color| try_parse_color(color).ok()),
701        terminal_ansi_dim_red: this
702            .terminal_ansi_dim_red
703            .as_ref()
704            .and_then(|color| try_parse_color(color).ok()),
705        terminal_ansi_green: this
706            .terminal_ansi_green
707            .as_ref()
708            .and_then(|color| try_parse_color(color).ok()),
709        terminal_ansi_bright_green: this
710            .terminal_ansi_bright_green
711            .as_ref()
712            .and_then(|color| try_parse_color(color).ok()),
713        terminal_ansi_dim_green: this
714            .terminal_ansi_dim_green
715            .as_ref()
716            .and_then(|color| try_parse_color(color).ok()),
717        terminal_ansi_yellow: this
718            .terminal_ansi_yellow
719            .as_ref()
720            .and_then(|color| try_parse_color(color).ok()),
721        terminal_ansi_bright_yellow: this
722            .terminal_ansi_bright_yellow
723            .as_ref()
724            .and_then(|color| try_parse_color(color).ok()),
725        terminal_ansi_dim_yellow: this
726            .terminal_ansi_dim_yellow
727            .as_ref()
728            .and_then(|color| try_parse_color(color).ok()),
729        terminal_ansi_blue: this
730            .terminal_ansi_blue
731            .as_ref()
732            .and_then(|color| try_parse_color(color).ok()),
733        terminal_ansi_bright_blue: this
734            .terminal_ansi_bright_blue
735            .as_ref()
736            .and_then(|color| try_parse_color(color).ok()),
737        terminal_ansi_dim_blue: this
738            .terminal_ansi_dim_blue
739            .as_ref()
740            .and_then(|color| try_parse_color(color).ok()),
741        terminal_ansi_magenta: this
742            .terminal_ansi_magenta
743            .as_ref()
744            .and_then(|color| try_parse_color(color).ok()),
745        terminal_ansi_bright_magenta: this
746            .terminal_ansi_bright_magenta
747            .as_ref()
748            .and_then(|color| try_parse_color(color).ok()),
749        terminal_ansi_dim_magenta: this
750            .terminal_ansi_dim_magenta
751            .as_ref()
752            .and_then(|color| try_parse_color(color).ok()),
753        terminal_ansi_cyan: this
754            .terminal_ansi_cyan
755            .as_ref()
756            .and_then(|color| try_parse_color(color).ok()),
757        terminal_ansi_bright_cyan: this
758            .terminal_ansi_bright_cyan
759            .as_ref()
760            .and_then(|color| try_parse_color(color).ok()),
761        terminal_ansi_dim_cyan: this
762            .terminal_ansi_dim_cyan
763            .as_ref()
764            .and_then(|color| try_parse_color(color).ok()),
765        terminal_ansi_white: this
766            .terminal_ansi_white
767            .as_ref()
768            .and_then(|color| try_parse_color(color).ok()),
769        terminal_ansi_bright_white: this
770            .terminal_ansi_bright_white
771            .as_ref()
772            .and_then(|color| try_parse_color(color).ok()),
773        terminal_ansi_dim_white: this
774            .terminal_ansi_dim_white
775            .as_ref()
776            .and_then(|color| try_parse_color(color).ok()),
777        link_text_hover: this
778            .link_text_hover
779            .as_ref()
780            .and_then(|color| try_parse_color(color).ok()),
781        version_control_added: this
782            .version_control_added
783            .as_ref()
784            .and_then(|color| try_parse_color(color).ok())
785            // Fall back to `created`, for backwards compatibility.
786            .or(status_colors.created),
787        version_control_deleted: this
788            .version_control_deleted
789            .as_ref()
790            .and_then(|color| try_parse_color(color).ok())
791            // Fall back to `deleted`, for backwards compatibility.
792            .or(status_colors.deleted),
793        version_control_modified: this
794            .version_control_modified
795            .as_ref()
796            .and_then(|color| try_parse_color(color).ok())
797            // Fall back to `modified`, for backwards compatibility.
798            .or(status_colors.modified),
799        version_control_renamed: this
800            .version_control_renamed
801            .as_ref()
802            .and_then(|color| try_parse_color(color).ok())
803            // Fall back to `modified`, for backwards compatibility.
804            .or(status_colors.modified),
805        version_control_conflict: this
806            .version_control_conflict
807            .as_ref()
808            .and_then(|color| try_parse_color(color).ok())
809            // Fall back to `ignored`, for backwards compatibility.
810            .or(status_colors.ignored),
811        version_control_ignored: this
812            .version_control_ignored
813            .as_ref()
814            .and_then(|color| try_parse_color(color).ok())
815            // Fall back to `conflict`, for backwards compatibility.
816            .or(status_colors.ignored),
817        #[allow(deprecated)]
818        version_control_conflict_marker_ours: this
819            .version_control_conflict_marker_ours
820            .as_ref()
821            .or(this.version_control_conflict_ours_background.as_ref())
822            .and_then(|color| try_parse_color(color).ok()),
823        #[allow(deprecated)]
824        version_control_conflict_marker_theirs: this
825            .version_control_conflict_marker_theirs
826            .as_ref()
827            .or(this.version_control_conflict_theirs_background.as_ref())
828            .and_then(|color| try_parse_color(color).ok()),
829    }
830}
831
832pub(crate) fn try_parse_color(color: &str) -> anyhow::Result<Hsla> {
833    let rgba = gpui::Rgba::try_from(color)?;
834    let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
835    let hsla = palette::Hsla::from_color(rgba);
836
837    let hsla = gpui::hsla(
838        hsla.hue.into_positive_degrees() / 360.,
839        hsla.saturation,
840        hsla.lightness,
841        hsla.alpha,
842    );
843
844    Ok(hsla)
845}