vscode.rs

  1use anyhow::Result;
  2use gpui::{Hsla, Refineable, Rgba};
  3use serde::Deserialize;
  4use theme::{
  5    Appearance, GitStatusColors, PlayerColors, StatusColors, SyntaxTheme, SystemColors,
  6    ThemeColors, ThemeColorsRefinement, ThemeStyles, ThemeVariant,
  7};
  8
  9use crate::util::Traverse;
 10use crate::ThemeMetadata;
 11
 12#[derive(Deserialize, Debug)]
 13pub struct VsCodeTheme {
 14    #[serde(rename = "$schema")]
 15    pub schema: Option<String>,
 16    pub name: Option<String>,
 17    pub author: Option<String>,
 18    pub maintainers: Option<Vec<String>>,
 19    #[serde(rename = "semanticClass")]
 20    pub semantic_class: Option<String>,
 21    #[serde(rename = "semanticHighlighting")]
 22    pub semantic_highlighting: Option<bool>,
 23    pub colors: VsCodeColors,
 24}
 25
 26#[derive(Debug, Deserialize)]
 27pub struct VsCodeColors {
 28    #[serde(rename = "terminal.background")]
 29    pub terminal_background: Option<String>,
 30    #[serde(rename = "terminal.foreground")]
 31    pub terminal_foreground: Option<String>,
 32    #[serde(rename = "terminal.ansiBrightBlack")]
 33    pub terminal_ansi_bright_black: Option<String>,
 34    #[serde(rename = "terminal.ansiBrightRed")]
 35    pub terminal_ansi_bright_red: Option<String>,
 36    #[serde(rename = "terminal.ansiBrightGreen")]
 37    pub terminal_ansi_bright_green: Option<String>,
 38    #[serde(rename = "terminal.ansiBrightYellow")]
 39    pub terminal_ansi_bright_yellow: Option<String>,
 40    #[serde(rename = "terminal.ansiBrightBlue")]
 41    pub terminal_ansi_bright_blue: Option<String>,
 42    #[serde(rename = "terminal.ansiBrightMagenta")]
 43    pub terminal_ansi_bright_magenta: Option<String>,
 44    #[serde(rename = "terminal.ansiBrightCyan")]
 45    pub terminal_ansi_bright_cyan: Option<String>,
 46    #[serde(rename = "terminal.ansiBrightWhite")]
 47    pub terminal_ansi_bright_white: Option<String>,
 48    #[serde(rename = "terminal.ansiBlack")]
 49    pub terminal_ansi_black: Option<String>,
 50    #[serde(rename = "terminal.ansiRed")]
 51    pub terminal_ansi_red: Option<String>,
 52    #[serde(rename = "terminal.ansiGreen")]
 53    pub terminal_ansi_green: Option<String>,
 54    #[serde(rename = "terminal.ansiYellow")]
 55    pub terminal_ansi_yellow: Option<String>,
 56    #[serde(rename = "terminal.ansiBlue")]
 57    pub terminal_ansi_blue: Option<String>,
 58    #[serde(rename = "terminal.ansiMagenta")]
 59    pub terminal_ansi_magenta: Option<String>,
 60    #[serde(rename = "terminal.ansiCyan")]
 61    pub terminal_ansi_cyan: Option<String>,
 62    #[serde(rename = "terminal.ansiWhite")]
 63    pub terminal_ansi_white: Option<String>,
 64    #[serde(rename = "focusBorder")]
 65    pub focus_border: Option<String>,
 66    pub foreground: Option<String>,
 67    #[serde(rename = "selection.background")]
 68    pub selection_background: Option<String>,
 69    #[serde(rename = "errorForeground")]
 70    pub error_foreground: Option<String>,
 71    #[serde(rename = "button.background")]
 72    pub button_background: Option<String>,
 73    #[serde(rename = "button.foreground")]
 74    pub button_foreground: Option<String>,
 75    #[serde(rename = "button.secondaryBackground")]
 76    pub button_secondary_background: Option<String>,
 77    #[serde(rename = "button.secondaryForeground")]
 78    pub button_secondary_foreground: Option<String>,
 79    #[serde(rename = "button.secondaryHoverBackground")]
 80    pub button_secondary_hover_background: Option<String>,
 81    #[serde(rename = "dropdown.background")]
 82    pub dropdown_background: Option<String>,
 83    #[serde(rename = "dropdown.border")]
 84    pub dropdown_border: Option<String>,
 85    #[serde(rename = "dropdown.foreground")]
 86    pub dropdown_foreground: Option<String>,
 87    #[serde(rename = "input.background")]
 88    pub input_background: Option<String>,
 89    #[serde(rename = "input.foreground")]
 90    pub input_foreground: Option<String>,
 91    #[serde(rename = "input.border")]
 92    pub input_border: Option<String>,
 93    #[serde(rename = "input.placeholderForeground")]
 94    pub input_placeholder_foreground: Option<String>,
 95    #[serde(rename = "inputOption.activeBorder")]
 96    pub input_option_active_border: Option<String>,
 97    #[serde(rename = "inputValidation.infoBorder")]
 98    pub input_validation_info_border: Option<String>,
 99    #[serde(rename = "inputValidation.warningBorder")]
100    pub input_validation_warning_border: Option<String>,
101    #[serde(rename = "inputValidation.errorBorder")]
102    pub input_validation_error_border: Option<String>,
103    #[serde(rename = "badge.foreground")]
104    pub badge_foreground: Option<String>,
105    #[serde(rename = "badge.background")]
106    pub badge_background: Option<String>,
107    #[serde(rename = "progressBar.background")]
108    pub progress_bar_background: Option<String>,
109    #[serde(rename = "list.activeSelectionBackground")]
110    pub list_active_selection_background: Option<String>,
111    #[serde(rename = "list.activeSelectionForeground")]
112    pub list_active_selection_foreground: Option<String>,
113    #[serde(rename = "list.dropBackground")]
114    pub list_drop_background: Option<String>,
115    #[serde(rename = "list.focusBackground")]
116    pub list_focus_background: Option<String>,
117    #[serde(rename = "list.highlightForeground")]
118    pub list_highlight_foreground: Option<String>,
119    #[serde(rename = "list.hoverBackground")]
120    pub list_hover_background: Option<String>,
121    #[serde(rename = "list.inactiveSelectionBackground")]
122    pub list_inactive_selection_background: Option<String>,
123    #[serde(rename = "list.warningForeground")]
124    pub list_warning_foreground: Option<String>,
125    #[serde(rename = "list.errorForeground")]
126    pub list_error_foreground: Option<String>,
127    #[serde(rename = "activityBar.background")]
128    pub activity_bar_background: Option<String>,
129    #[serde(rename = "activityBar.inactiveForeground")]
130    pub activity_bar_inactive_foreground: Option<String>,
131    #[serde(rename = "activityBar.foreground")]
132    pub activity_bar_foreground: Option<String>,
133    #[serde(rename = "activityBar.activeBorder")]
134    pub activity_bar_active_border: Option<String>,
135    #[serde(rename = "activityBar.activeBackground")]
136    pub activity_bar_active_background: Option<String>,
137    #[serde(rename = "activityBarBadge.background")]
138    pub activity_bar_badge_background: Option<String>,
139    #[serde(rename = "activityBarBadge.foreground")]
140    pub activity_bar_badge_foreground: Option<String>,
141    #[serde(rename = "sideBar.background")]
142    pub side_bar_background: Option<String>,
143    #[serde(rename = "sideBarTitle.foreground")]
144    pub side_bar_title_foreground: Option<String>,
145    #[serde(rename = "sideBarSectionHeader.background")]
146    pub side_bar_section_header_background: Option<String>,
147    #[serde(rename = "sideBarSectionHeader.border")]
148    pub side_bar_section_header_border: Option<String>,
149    #[serde(rename = "editorGroup.border")]
150    pub editor_group_border: Option<String>,
151    #[serde(rename = "editorGroup.dropBackground")]
152    pub editor_group_drop_background: Option<String>,
153    #[serde(rename = "editorGroupHeader.tabsBackground")]
154    pub editor_group_header_tabs_background: Option<String>,
155    #[serde(rename = "tab.activeBackground")]
156    pub tab_active_background: Option<String>,
157    #[serde(rename = "tab.activeForeground")]
158    pub tab_active_foreground: Option<String>,
159    #[serde(rename = "tab.border")]
160    pub tab_border: Option<String>,
161    #[serde(rename = "tab.activeBorderTop")]
162    pub tab_active_border_top: Option<String>,
163    #[serde(rename = "tab.inactiveBackground")]
164    pub tab_inactive_background: Option<String>,
165    #[serde(rename = "tab.inactiveForeground")]
166    pub tab_inactive_foreground: Option<String>,
167    #[serde(rename = "editor.foreground")]
168    pub editor_foreground: Option<String>,
169    #[serde(rename = "editor.background")]
170    pub editor_background: Option<String>,
171    #[serde(rename = "editorLineNumber.foreground")]
172    pub editor_line_number_foreground: Option<String>,
173    #[serde(rename = "editor.selectionBackground")]
174    pub editor_selection_background: Option<String>,
175    #[serde(rename = "editor.selectionHighlightBackground")]
176    pub editor_selection_highlight_background: Option<String>,
177    #[serde(rename = "editor.foldBackground")]
178    pub editor_fold_background: Option<String>,
179    #[serde(rename = "editor.wordHighlightBackground")]
180    pub editor_word_highlight_background: Option<String>,
181    #[serde(rename = "editor.wordHighlightStrongBackground")]
182    pub editor_word_highlight_strong_background: Option<String>,
183    #[serde(rename = "editor.findMatchBackground")]
184    pub editor_find_match_background: Option<String>,
185    #[serde(rename = "editor.findMatchHighlightBackground")]
186    pub editor_find_match_highlight_background: Option<String>,
187    #[serde(rename = "editor.findRangeHighlightBackground")]
188    pub editor_find_range_highlight_background: Option<String>,
189    #[serde(rename = "editor.hoverHighlightBackground")]
190    pub editor_hover_highlight_background: Option<String>,
191    #[serde(rename = "editor.lineHighlightBorder")]
192    pub editor_line_highlight_border: Option<String>,
193    #[serde(rename = "editorLink.activeForeground")]
194    pub editor_link_active_foreground: Option<String>,
195    #[serde(rename = "editor.rangeHighlightBackground")]
196    pub editor_range_highlight_background: Option<String>,
197    #[serde(rename = "editor.snippetTabstopHighlightBackground")]
198    pub editor_snippet_tabstop_highlight_background: Option<String>,
199    #[serde(rename = "editor.snippetTabstopHighlightBorder")]
200    pub editor_snippet_tabstop_highlight_border: Option<String>,
201    #[serde(rename = "editor.snippetFinalTabstopHighlightBackground")]
202    pub editor_snippet_final_tabstop_highlight_background: Option<String>,
203    #[serde(rename = "editor.snippetFinalTabstopHighlightBorder")]
204    pub editor_snippet_final_tabstop_highlight_border: Option<String>,
205    #[serde(rename = "editorWhitespace.foreground")]
206    pub editor_whitespace_foreground: Option<String>,
207    #[serde(rename = "editorIndentGuide.background")]
208    pub editor_indent_guide_background: Option<String>,
209    #[serde(rename = "editorIndentGuide.activeBackground")]
210    pub editor_indent_guide_active_background: Option<String>,
211    #[serde(rename = "editorRuler.foreground")]
212    pub editor_ruler_foreground: Option<String>,
213    #[serde(rename = "editorCodeLens.foreground")]
214    pub editor_code_lens_foreground: Option<String>,
215    #[serde(rename = "editorBracketHighlight.foreground1")]
216    pub editor_bracket_highlight_foreground1: Option<String>,
217    #[serde(rename = "editorBracketHighlight.foreground2")]
218    pub editor_bracket_highlight_foreground2: Option<String>,
219    #[serde(rename = "editorBracketHighlight.foreground3")]
220    pub editor_bracket_highlight_foreground3: Option<String>,
221    #[serde(rename = "editorBracketHighlight.foreground4")]
222    pub editor_bracket_highlight_foreground4: Option<String>,
223    #[serde(rename = "editorBracketHighlight.foreground5")]
224    pub editor_bracket_highlight_foreground5: Option<String>,
225    #[serde(rename = "editorBracketHighlight.foreground6")]
226    pub editor_bracket_highlight_foreground6: Option<String>,
227    #[serde(rename = "editorBracketHighlight.unexpectedBracket.foreground")]
228    pub editor_bracket_highlight_unexpected_bracket_foreground: Option<String>,
229    #[serde(rename = "editorOverviewRuler.border")]
230    pub editor_overview_ruler_border: Option<String>,
231    #[serde(rename = "editorOverviewRuler.selectionHighlightForeground")]
232    pub editor_overview_ruler_selection_highlight_foreground: Option<String>,
233    #[serde(rename = "editorOverviewRuler.wordHighlightForeground")]
234    pub editor_overview_ruler_word_highlight_foreground: Option<String>,
235    #[serde(rename = "editorOverviewRuler.wordHighlightStrongForeground")]
236    pub editor_overview_ruler_word_highlight_strong_foreground: Option<String>,
237    #[serde(rename = "editorOverviewRuler.modifiedForeground")]
238    pub editor_overview_ruler_modified_foreground: Option<String>,
239    #[serde(rename = "editorOverviewRuler.addedForeground")]
240    pub editor_overview_ruler_added_foreground: Option<String>,
241    #[serde(rename = "editorOverviewRuler.deletedForeground")]
242    pub editor_overview_ruler_deleted_foreground: Option<String>,
243    #[serde(rename = "editorOverviewRuler.errorForeground")]
244    pub editor_overview_ruler_error_foreground: Option<String>,
245    #[serde(rename = "editorOverviewRuler.warningForeground")]
246    pub editor_overview_ruler_warning_foreground: Option<String>,
247    #[serde(rename = "editorOverviewRuler.infoForeground")]
248    pub editor_overview_ruler_info_foreground: Option<String>,
249    #[serde(rename = "editorError.foreground")]
250    pub editor_error_foreground: Option<String>,
251    #[serde(rename = "editorWarning.foreground")]
252    pub editor_warning_foreground: Option<String>,
253    #[serde(rename = "editorGutter.modifiedBackground")]
254    pub editor_gutter_modified_background: Option<String>,
255    #[serde(rename = "editorGutter.addedBackground")]
256    pub editor_gutter_added_background: Option<String>,
257    #[serde(rename = "editorGutter.deletedBackground")]
258    pub editor_gutter_deleted_background: Option<String>,
259    #[serde(rename = "gitDecoration.modifiedResourceForeground")]
260    pub git_decoration_modified_resource_foreground: Option<String>,
261    #[serde(rename = "gitDecoration.deletedResourceForeground")]
262    pub git_decoration_deleted_resource_foreground: Option<String>,
263    #[serde(rename = "gitDecoration.untrackedResourceForeground")]
264    pub git_decoration_untracked_resource_foreground: Option<String>,
265    #[serde(rename = "gitDecoration.ignoredResourceForeground")]
266    pub git_decoration_ignored_resource_foreground: Option<String>,
267    #[serde(rename = "gitDecoration.conflictingResourceForeground")]
268    pub git_decoration_conflicting_resource_foreground: Option<String>,
269    #[serde(rename = "diffEditor.insertedTextBackground")]
270    pub diff_editor_inserted_text_background: Option<String>,
271    #[serde(rename = "diffEditor.removedTextBackground")]
272    pub diff_editor_removed_text_background: Option<String>,
273    #[serde(rename = "inlineChat.regionHighlight")]
274    pub inline_chat_region_highlight: Option<String>,
275    #[serde(rename = "editorWidget.background")]
276    pub editor_widget_background: Option<String>,
277    #[serde(rename = "editorSuggestWidget.background")]
278    pub editor_suggest_widget_background: Option<String>,
279    #[serde(rename = "editorSuggestWidget.foreground")]
280    pub editor_suggest_widget_foreground: Option<String>,
281    #[serde(rename = "editorSuggestWidget.selectedBackground")]
282    pub editor_suggest_widget_selected_background: Option<String>,
283    #[serde(rename = "editorHoverWidget.background")]
284    pub editor_hover_widget_background: Option<String>,
285    #[serde(rename = "editorHoverWidget.border")]
286    pub editor_hover_widget_border: Option<String>,
287    #[serde(rename = "editorMarkerNavigation.background")]
288    pub editor_marker_navigation_background: Option<String>,
289    #[serde(rename = "peekView.border")]
290    pub peek_view_border: Option<String>,
291    #[serde(rename = "peekViewEditor.background")]
292    pub peek_view_editor_background: Option<String>,
293    #[serde(rename = "peekViewEditor.matchHighlightBackground")]
294    pub peek_view_editor_match_highlight_background: Option<String>,
295    #[serde(rename = "peekViewResult.background")]
296    pub peek_view_result_background: Option<String>,
297    #[serde(rename = "peekViewResult.fileForeground")]
298    pub peek_view_result_file_foreground: Option<String>,
299    #[serde(rename = "peekViewResult.lineForeground")]
300    pub peek_view_result_line_foreground: Option<String>,
301    #[serde(rename = "peekViewResult.matchHighlightBackground")]
302    pub peek_view_result_match_highlight_background: Option<String>,
303    #[serde(rename = "peekViewResult.selectionBackground")]
304    pub peek_view_result_selection_background: Option<String>,
305    #[serde(rename = "peekViewResult.selectionForeground")]
306    pub peek_view_result_selection_foreground: Option<String>,
307    #[serde(rename = "peekViewTitle.background")]
308    pub peek_view_title_background: Option<String>,
309    #[serde(rename = "peekViewTitleDescription.foreground")]
310    pub peek_view_title_description_foreground: Option<String>,
311    #[serde(rename = "peekViewTitleLabel.foreground")]
312    pub peek_view_title_label_foreground: Option<String>,
313    #[serde(rename = "merge.currentHeaderBackground")]
314    pub merge_current_header_background: Option<String>,
315    #[serde(rename = "merge.incomingHeaderBackground")]
316    pub merge_incoming_header_background: Option<String>,
317    #[serde(rename = "editorOverviewRuler.currentContentForeground")]
318    pub editor_overview_ruler_current_content_foreground: Option<String>,
319    #[serde(rename = "editorOverviewRuler.incomingContentForeground")]
320    pub editor_overview_ruler_incoming_content_foreground: Option<String>,
321    #[serde(rename = "panel.background")]
322    pub panel_background: Option<String>,
323    #[serde(rename = "panel.border")]
324    pub panel_border: Option<String>,
325    #[serde(rename = "panelTitle.activeBorder")]
326    pub panel_title_active_border: Option<String>,
327    #[serde(rename = "panelTitle.activeForeground")]
328    pub panel_title_active_foreground: Option<String>,
329    #[serde(rename = "panelTitle.inactiveForeground")]
330    pub panel_title_inactive_foreground: Option<String>,
331    #[serde(rename = "statusBar.background")]
332    pub status_bar_background: Option<String>,
333    #[serde(rename = "statusBar.foreground")]
334    pub status_bar_foreground: Option<String>,
335    #[serde(rename = "statusBar.debuggingBackground")]
336    pub status_bar_debugging_background: Option<String>,
337    #[serde(rename = "statusBar.debuggingForeground")]
338    pub status_bar_debugging_foreground: Option<String>,
339    #[serde(rename = "statusBar.noFolderBackground")]
340    pub status_bar_no_folder_background: Option<String>,
341    #[serde(rename = "statusBar.noFolderForeground")]
342    pub status_bar_no_folder_foreground: Option<String>,
343    #[serde(rename = "statusBarItem.prominentBackground")]
344    pub status_bar_item_prominent_background: Option<String>,
345    #[serde(rename = "statusBarItem.prominentHoverBackground")]
346    pub status_bar_item_prominent_hover_background: Option<String>,
347    #[serde(rename = "statusBarItem.remoteForeground")]
348    pub status_bar_item_remote_foreground: Option<String>,
349    #[serde(rename = "statusBarItem.remoteBackground")]
350    pub status_bar_item_remote_background: Option<String>,
351    #[serde(rename = "titleBar.activeBackground")]
352    pub title_bar_active_background: Option<String>,
353    #[serde(rename = "titleBar.activeForeground")]
354    pub title_bar_active_foreground: Option<String>,
355    #[serde(rename = "titleBar.inactiveBackground")]
356    pub title_bar_inactive_background: Option<String>,
357    #[serde(rename = "titleBar.inactiveForeground")]
358    pub title_bar_inactive_foreground: Option<String>,
359    #[serde(rename = "extensionButton.prominentForeground")]
360    pub extension_button_prominent_foreground: Option<String>,
361    #[serde(rename = "extensionButton.prominentBackground")]
362    pub extension_button_prominent_background: Option<String>,
363    #[serde(rename = "extensionButton.prominentHoverBackground")]
364    pub extension_button_prominent_hover_background: Option<String>,
365    #[serde(rename = "pickerGroup.border")]
366    pub picker_group_border: Option<String>,
367    #[serde(rename = "pickerGroup.foreground")]
368    pub picker_group_foreground: Option<String>,
369    #[serde(rename = "debugToolBar.background")]
370    pub debug_tool_bar_background: Option<String>,
371    #[serde(rename = "walkThrough.embeddedEditorBackground")]
372    pub walk_through_embedded_editor_background: Option<String>,
373    #[serde(rename = "settings.headerForeground")]
374    pub settings_header_foreground: Option<String>,
375    #[serde(rename = "settings.modifiedItemIndicator")]
376    pub settings_modified_item_indicator: Option<String>,
377    #[serde(rename = "settings.dropdownBackground")]
378    pub settings_dropdown_background: Option<String>,
379    #[serde(rename = "settings.dropdownForeground")]
380    pub settings_dropdown_foreground: Option<String>,
381    #[serde(rename = "settings.dropdownBorder")]
382    pub settings_dropdown_border: Option<String>,
383    #[serde(rename = "settings.checkboxBackground")]
384    pub settings_checkbox_background: Option<String>,
385    #[serde(rename = "settings.checkboxForeground")]
386    pub settings_checkbox_foreground: Option<String>,
387    #[serde(rename = "settings.checkboxBorder")]
388    pub settings_checkbox_border: Option<String>,
389    #[serde(rename = "settings.textInputBackground")]
390    pub settings_text_input_background: Option<String>,
391    #[serde(rename = "settings.textInputForeground")]
392    pub settings_text_input_foreground: Option<String>,
393    #[serde(rename = "settings.textInputBorder")]
394    pub settings_text_input_border: Option<String>,
395    #[serde(rename = "settings.numberInputBackground")]
396    pub settings_number_input_background: Option<String>,
397    #[serde(rename = "settings.numberInputForeground")]
398    pub settings_number_input_foreground: Option<String>,
399    #[serde(rename = "settings.numberInputBorder")]
400    pub settings_number_input_border: Option<String>,
401    #[serde(rename = "breadcrumb.foreground")]
402    pub breadcrumb_foreground: Option<String>,
403    #[serde(rename = "breadcrumb.background")]
404    pub breadcrumb_background: Option<String>,
405    #[serde(rename = "breadcrumb.focusForeground")]
406    pub breadcrumb_focus_foreground: Option<String>,
407    #[serde(rename = "breadcrumb.activeSelectionForeground")]
408    pub breadcrumb_active_selection_foreground: Option<String>,
409    #[serde(rename = "breadcrumbPicker.background")]
410    pub breadcrumb_picker_background: Option<String>,
411    #[serde(rename = "listFilterWidget.background")]
412    pub list_filter_widget_background: Option<String>,
413    #[serde(rename = "listFilterWidget.outline")]
414    pub list_filter_widget_outline: Option<String>,
415    #[serde(rename = "listFilterWidget.noMatchesOutline")]
416    pub list_filter_widget_no_matches_outline: Option<String>,
417}
418
419fn try_parse_color(color: &str) -> Result<Hsla> {
420    Ok(Rgba::try_from(color)?.into())
421}
422
423pub struct VsCodeThemeConverter {
424    theme: VsCodeTheme,
425    theme_metadata: ThemeMetadata,
426}
427
428impl VsCodeThemeConverter {
429    pub fn new(theme: VsCodeTheme, theme_metadata: ThemeMetadata) -> Self {
430        Self {
431            theme,
432            theme_metadata,
433        }
434    }
435
436    pub fn convert(self) -> Result<ThemeVariant> {
437        let appearance = self.theme_metadata.appearance.into();
438
439        let mut theme_colors = match appearance {
440            Appearance::Light => ThemeColors::default_light(),
441            Appearance::Dark => ThemeColors::default_dark(),
442        };
443
444        let vscode_colors = &self.theme.colors;
445
446        let theme_colors_refinements = ThemeColorsRefinement {
447            border: vscode_colors
448                .panel_border
449                .as_ref()
450                .traverse(|color| try_parse_color(&color))?,
451            border_variant: vscode_colors
452                .panel_border
453                .as_ref()
454                .traverse(|color| try_parse_color(&color))?,
455            border_focused: vscode_colors
456                .panel_border
457                .as_ref()
458                .traverse(|color| try_parse_color(&color))?,
459            border_transparent: vscode_colors
460                .panel_border
461                .as_ref()
462                .traverse(|color| try_parse_color(&color))?,
463            elevated_surface_background: vscode_colors
464                .panel_background
465                .as_ref()
466                .traverse(|color| try_parse_color(&color))?,
467            surface_background: vscode_colors
468                .panel_background
469                .as_ref()
470                .traverse(|color| try_parse_color(&color))?,
471            background: vscode_colors
472                .editor_background
473                .as_ref()
474                .traverse(|color| try_parse_color(&color))?,
475            element_background: vscode_colors
476                .button_background
477                .as_ref()
478                .traverse(|color| try_parse_color(&color))?,
479            text: vscode_colors
480                .foreground
481                .as_ref()
482                .traverse(|color| try_parse_color(&color))?,
483            tab_active_background: vscode_colors
484                .tab_active_background
485                .as_ref()
486                .traverse(|color| try_parse_color(&color))?,
487            tab_inactive_background: vscode_colors
488                .tab_inactive_background
489                .as_ref()
490                .traverse(|color| try_parse_color(&color))?,
491            terminal_background: vscode_colors
492                .terminal_background
493                .as_ref()
494                .traverse(|color| try_parse_color(&color))?,
495            terminal_ansi_bright_black: vscode_colors
496                .terminal_ansi_bright_black
497                .as_ref()
498                .traverse(|color| try_parse_color(&color))?,
499            terminal_ansi_bright_red: vscode_colors
500                .terminal_ansi_bright_red
501                .as_ref()
502                .traverse(|color| try_parse_color(&color))?,
503            terminal_ansi_bright_green: vscode_colors
504                .terminal_ansi_bright_green
505                .as_ref()
506                .traverse(|color| try_parse_color(&color))?,
507            terminal_ansi_bright_yellow: vscode_colors
508                .terminal_ansi_bright_yellow
509                .as_ref()
510                .traverse(|color| try_parse_color(&color))?,
511            terminal_ansi_bright_blue: vscode_colors
512                .terminal_ansi_bright_blue
513                .as_ref()
514                .traverse(|color| try_parse_color(&color))?,
515            terminal_ansi_bright_magenta: vscode_colors
516                .terminal_ansi_bright_magenta
517                .as_ref()
518                .traverse(|color| try_parse_color(&color))?,
519            terminal_ansi_bright_cyan: vscode_colors
520                .terminal_ansi_bright_cyan
521                .as_ref()
522                .traverse(|color| try_parse_color(&color))?,
523            terminal_ansi_bright_white: vscode_colors
524                .terminal_ansi_bright_white
525                .as_ref()
526                .traverse(|color| try_parse_color(&color))?,
527            terminal_ansi_black: vscode_colors
528                .terminal_ansi_black
529                .as_ref()
530                .traverse(|color| try_parse_color(&color))?,
531            terminal_ansi_red: vscode_colors
532                .terminal_ansi_red
533                .as_ref()
534                .traverse(|color| try_parse_color(&color))?,
535            terminal_ansi_green: vscode_colors
536                .terminal_ansi_green
537                .as_ref()
538                .traverse(|color| try_parse_color(&color))?,
539            terminal_ansi_yellow: vscode_colors
540                .terminal_ansi_yellow
541                .as_ref()
542                .traverse(|color| try_parse_color(&color))?,
543            terminal_ansi_blue: vscode_colors
544                .terminal_ansi_blue
545                .as_ref()
546                .traverse(|color| try_parse_color(&color))?,
547            terminal_ansi_magenta: vscode_colors
548                .terminal_ansi_magenta
549                .as_ref()
550                .traverse(|color| try_parse_color(&color))?,
551            terminal_ansi_cyan: vscode_colors
552                .terminal_ansi_cyan
553                .as_ref()
554                .traverse(|color| try_parse_color(&color))?,
555            terminal_ansi_white: vscode_colors
556                .terminal_ansi_white
557                .as_ref()
558                .traverse(|color| try_parse_color(&color))?,
559            ..Default::default()
560        };
561
562        theme_colors.refine(&theme_colors_refinements);
563
564        Ok(ThemeVariant {
565            id: uuid::Uuid::new_v4().to_string(),
566            name: self.theme_metadata.name.into(),
567            appearance,
568            styles: ThemeStyles {
569                system: SystemColors::default(),
570                colors: theme_colors,
571                status: StatusColors::default(),
572                git: GitStatusColors::default(),
573                player: PlayerColors::default(),
574                syntax: SyntaxTheme::default_dark(),
575            },
576        })
577    }
578}
579
580// #[cfg(test)]
581// mod tests {
582//     use super::*;
583//     use std::path::PathBuf;
584
585//     #[test]
586//     fn test_deserialize_theme() {
587//         let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
588//         let root_dir = manifest_dir.parent().unwrap().parent().unwrap();
589
590//         let mut d = root_dir.to_path_buf();
591//         d.push("assets/themes/src/vsc/dracula/dracula.json");
592
593//         let data = std::fs::read_to_string(d).expect("Unable to read file");
594
595//         let result: Theme = serde_json::from_str(&data).unwrap();
596//         println!("{:#?}", result);
597//     }
598// }