schema.rs

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