schema.rs

   1use anyhow::Result;
   2use gpui::{HighlightStyle, Hsla};
   3use indexmap::IndexMap;
   4use palette::FromColor;
   5use schemars::JsonSchema;
   6use serde::{Deserialize, Serialize};
   7
   8use crate::{StatusColorsRefinement, ThemeColorsRefinement};
   9
  10fn try_parse_color(color: &str) -> Result<Hsla> {
  11    let rgba = gpui::Rgba::try_from(color)?;
  12    let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
  13    let hsla = palette::Hsla::from_color(rgba);
  14
  15    let hsla = gpui::hsla(
  16        hsla.hue.into_positive_degrees() / 360.,
  17        hsla.saturation,
  18        hsla.lightness,
  19        hsla.alpha,
  20    );
  21
  22    Ok(hsla)
  23}
  24
  25/// The content of a serialized theme.
  26#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
  27#[serde(default)]
  28pub struct ThemeContent {
  29    #[serde(flatten, default)]
  30    pub colors: ThemeColorsContent,
  31
  32    #[serde(flatten, default)]
  33    pub status: StatusColorsContent,
  34
  35    /// The styles for syntax nodes.
  36    #[serde(default)]
  37    pub syntax: IndexMap<String, HighlightStyleContent>,
  38}
  39
  40impl ThemeContent {
  41    /// Returns a [`ThemeColorsRefinement`] based on the colors in the [`ThemeContent`].
  42    #[inline(always)]
  43    pub fn theme_colors_refinement(&self) -> ThemeColorsRefinement {
  44        self.colors.theme_colors_refinement()
  45    }
  46
  47    /// Returns a [`StatusColorsRefinement`] based on the colors in the [`ThemeContent`].
  48    #[inline(always)]
  49    pub fn status_colors_refinement(&self) -> StatusColorsRefinement {
  50        self.status.status_colors_refinement()
  51    }
  52
  53    /// Returns the syntax style overrides in the [`ThemeContent`].
  54    pub fn syntax_overrides(&self) -> Vec<(String, HighlightStyle)> {
  55        self.syntax
  56            .iter()
  57            .map(|(key, style)| {
  58                (
  59                    key.clone(),
  60                    HighlightStyle {
  61                        color: style
  62                            .color
  63                            .as_ref()
  64                            .and_then(|color| try_parse_color(&color).ok()),
  65                        ..Default::default()
  66                    },
  67                )
  68            })
  69            .collect()
  70    }
  71}
  72
  73#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
  74#[serde(default)]
  75pub struct ThemeColorsContent {
  76    /// Border color. Used for most borders, is usually a high contrast color.
  77    #[serde(rename = "border")]
  78    pub border: Option<String>,
  79
  80    /// Border color. Used for deemphasized borders, like a visual divider between two sections
  81    #[serde(rename = "border.variant")]
  82    pub border_variant: Option<String>,
  83
  84    /// Border color. Used for focused elements, like keyboard focused list item.
  85    #[serde(rename = "border.focused")]
  86    pub border_focused: Option<String>,
  87
  88    /// Border color. Used for selected elements, like an active search filter or selected checkbox.
  89    #[serde(rename = "border.selected")]
  90    pub border_selected: Option<String>,
  91
  92    /// Border color. Used for transparent borders. Used for placeholder borders when an element gains a border on state change.
  93    #[serde(rename = "border.transparent")]
  94    pub border_transparent: Option<String>,
  95
  96    /// Border color. Used for disabled elements, like a disabled input or button.
  97    #[serde(rename = "border.disabled")]
  98    pub border_disabled: Option<String>,
  99
 100    /// Border color. Used for elevated surfaces, like a context menu, popup, or dialog.
 101    #[serde(rename = "elevated_surface.background")]
 102    pub elevated_surface_background: Option<String>,
 103
 104    /// Background Color. Used for grounded surfaces like a panel or tab.
 105    #[serde(rename = "surface.background")]
 106    pub surface_background: Option<String>,
 107
 108    /// Background Color. Used for the app background and blank panels or windows.
 109    #[serde(rename = "background")]
 110    pub background: Option<String>,
 111
 112    /// Background Color. Used for the background of an element that should have a different background than the surface it's on.
 113    ///
 114    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 115    ///
 116    /// For an element that should have the same background as the surface it's on, use `ghost_element_background`.
 117    #[serde(rename = "element.background")]
 118    pub element_background: Option<String>,
 119
 120    /// Background Color. Used for the hover state of an element that should have a different background than the surface it's on.
 121    ///
 122    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 123    #[serde(rename = "element.hover")]
 124    pub element_hover: Option<String>,
 125
 126    /// Background Color. Used for the active state of an element that should have a different background than the surface it's on.
 127    ///
 128    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 129    #[serde(rename = "element.active")]
 130    pub element_active: Option<String>,
 131
 132    /// Background Color. Used for the selected state of an element that should have a different background than the surface it's on.
 133    ///
 134    /// Selected states are triggered by the element being selected (or "activated") by the user.
 135    ///
 136    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 137    #[serde(rename = "element.selected")]
 138    pub element_selected: Option<String>,
 139
 140    /// Background Color. Used for the disabled state of an element that should have a different background than the surface it's on.
 141    ///
 142    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 143    #[serde(rename = "element.disabled")]
 144    pub element_disabled: Option<String>,
 145
 146    /// Background Color. Used for the area that shows where a dragged element will be dropped.
 147    #[serde(rename = "drop_target.background")]
 148    pub drop_target_background: Option<String>,
 149
 150    /// Used for the background of a ghost element that should have the same background as the surface it's on.
 151    ///
 152    /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
 153    ///
 154    /// For an element that should have a different background than the surface it's on, use `element_background`.
 155    #[serde(rename = "ghost_element.background")]
 156    pub ghost_element_background: Option<String>,
 157
 158    /// Background Color. Used for the hover state of a ghost element that should have the same background as the surface it's on.
 159    ///
 160    /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
 161    #[serde(rename = "ghost_element.hover")]
 162    pub ghost_element_hover: Option<String>,
 163
 164    /// Background Color. Used for the active state of a ghost element that should have the same background as the surface it's on.
 165    ///
 166    /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
 167    #[serde(rename = "ghost_element.active")]
 168    pub ghost_element_active: Option<String>,
 169
 170    /// Background Color. Used for the selected state of a ghost element that should have the same background as the surface it's on.
 171    ///
 172    /// Selected states are triggered by the element being selected (or "activated") by the user.
 173    ///
 174    /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
 175    #[serde(rename = "ghost_element.selected")]
 176    pub ghost_element_selected: Option<String>,
 177
 178    /// Background Color. Used for the disabled state of a ghost element that should have the same background as the surface it's on.
 179    ///
 180    /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
 181    #[serde(rename = "ghost_element.disabled")]
 182    pub ghost_element_disabled: Option<String>,
 183
 184    /// Text Color. Default text color used for most text.
 185    #[serde(rename = "text")]
 186    pub text: Option<String>,
 187
 188    /// Text Color. Color of muted or deemphasized text. It is a subdued version of the standard text color.
 189    #[serde(rename = "text.muted")]
 190    pub text_muted: Option<String>,
 191
 192    /// Text Color. Color of the placeholder text typically shown in input fields to guide the user to enter valid data.
 193    #[serde(rename = "text.placeholder")]
 194    pub text_placeholder: Option<String>,
 195
 196    /// Text Color. Color used for text denoting disabled elements. Typically, the color is faded or grayed out to emphasize the disabled state.
 197    #[serde(rename = "text.disabled")]
 198    pub text_disabled: Option<String>,
 199
 200    /// Text Color. Color used for emphasis or highlighting certain text, like an active filter or a matched character in a search.
 201    #[serde(rename = "text.accent")]
 202    pub text_accent: Option<String>,
 203
 204    /// Fill Color. Used for the default fill color of an icon.
 205    #[serde(rename = "icon")]
 206    pub icon: Option<String>,
 207
 208    /// Fill Color. Used for the muted or deemphasized fill color of an icon.
 209    ///
 210    /// This might be used to show an icon in an inactive pane, or to demphasize a series of icons to give them less visual weight.
 211    #[serde(rename = "icon.muted")]
 212    pub icon_muted: Option<String>,
 213
 214    /// Fill Color. Used for the disabled fill color of an icon.
 215    ///
 216    /// Disabled states are shown when a user cannot interact with an element, like a icon button.
 217    #[serde(rename = "icon.disabled")]
 218    pub icon_disabled: Option<String>,
 219
 220    /// Fill Color. Used for the placeholder fill color of an icon.
 221    ///
 222    /// This might be used to show an icon in an input that disappears when the user enters text.
 223    #[serde(rename = "icon.placeholder")]
 224    pub icon_placeholder: Option<String>,
 225
 226    /// Fill Color. Used for the accent fill color of an icon.
 227    ///
 228    /// This might be used to show when a toggleable icon button is selected.
 229    #[serde(rename = "con.accent")]
 230    pub icon_accent: Option<String>,
 231
 232    #[serde(rename = "status_bar.background")]
 233    pub status_bar_background: Option<String>,
 234
 235    #[serde(rename = "title_bar.background")]
 236    pub title_bar_background: Option<String>,
 237
 238    #[serde(rename = "toolbar.background")]
 239    pub toolbar_background: Option<String>,
 240
 241    #[serde(rename = "tab_bar.background")]
 242    pub tab_bar_background: Option<String>,
 243
 244    #[serde(rename = "tab.inactive_background")]
 245    pub tab_inactive_background: Option<String>,
 246
 247    #[serde(rename = "tab.active_background")]
 248    pub tab_active_background: Option<String>,
 249
 250    #[serde(rename = "search.match_background")]
 251    pub search_match_background: Option<String>,
 252
 253    #[serde(rename = "panel.background")]
 254    pub panel_background: Option<String>,
 255
 256    #[serde(rename = "panel.focused_border")]
 257    pub panel_focused_border: Option<String>,
 258
 259    #[serde(rename = "pane.focused_border")]
 260    pub pane_focused_border: Option<String>,
 261
 262    /// The color of the scrollbar thumb.
 263    #[serde(rename = "scrollbar_thumb.background")]
 264    pub scrollbar_thumb_background: Option<String>,
 265
 266    /// The color of the scrollbar thumb when hovered over.
 267    #[serde(rename = "scrollbar.thumb.hover_background")]
 268    pub scrollbar_thumb_hover_background: Option<String>,
 269
 270    /// The border color of the scrollbar thumb.
 271    #[serde(rename = "scrollbar.thumb.border")]
 272    pub scrollbar_thumb_border: Option<String>,
 273
 274    /// The background color of the scrollbar track.
 275    #[serde(rename = "scrollbar.track.background")]
 276    pub scrollbar_track_background: Option<String>,
 277
 278    /// The border color of the scrollbar track.
 279    #[serde(rename = "scrollbar.track.border")]
 280    pub scrollbar_track_border: Option<String>,
 281
 282    #[serde(rename = "editor.foreground")]
 283    pub editor_foreground: Option<String>,
 284
 285    #[serde(rename = "editor.background")]
 286    pub editor_background: Option<String>,
 287
 288    #[serde(rename = "editor.gutter.background")]
 289    pub editor_gutter_background: Option<String>,
 290
 291    #[serde(rename = "editor.subheader.background")]
 292    pub editor_subheader_background: Option<String>,
 293
 294    #[serde(rename = "editor.active_line.background")]
 295    pub editor_active_line_background: Option<String>,
 296
 297    #[serde(rename = "editor.highlighted_line.background")]
 298    pub editor_highlighted_line_background: Option<String>,
 299
 300    /// Text Color. Used for the text of the line number in the editor gutter.
 301    #[serde(rename = "editor.line_number")]
 302    pub editor_line_number: Option<String>,
 303
 304    /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
 305    #[serde(rename = "editor.active_line_number")]
 306    pub editor_active_line_number: Option<String>,
 307
 308    /// Text Color. Used to mark invisible characters in the editor.
 309    ///
 310    /// Example: spaces, tabs, carriage returns, etc.
 311    #[serde(rename = "editor.invisible")]
 312    pub editor_invisible: Option<String>,
 313
 314    #[serde(rename = "editor.wrap_guide")]
 315    pub editor_wrap_guide: Option<String>,
 316
 317    #[serde(rename = "editor.active_wrap_guide")]
 318    pub editor_active_wrap_guide: Option<String>,
 319
 320    /// Read-access of a symbol, like reading a variable.
 321    ///
 322    /// A document highlight is a range inside a text document which deserves
 323    /// special attention. Usually a document highlight is visualized by changing
 324    /// the background color of its range.
 325    #[serde(rename = "editor.document_highlight.read_background")]
 326    pub editor_document_highlight_read_background: Option<String>,
 327
 328    /// Read-access of a symbol, like reading a variable.
 329    ///
 330    /// A document highlight is a range inside a text document which deserves
 331    /// special attention. Usually a document highlight is visualized by changing
 332    /// the background color of its range.
 333    #[serde(rename = "editor.document_highlight.write_background")]
 334    pub editor_document_highlight_write_background: Option<String>,
 335
 336    /// Terminal background color.
 337    #[serde(rename = "terminal.background")]
 338    pub terminal_background: Option<String>,
 339
 340    /// Terminal foreground color.
 341    #[serde(rename = "terminal.foreground")]
 342    pub terminal_foreground: Option<String>,
 343
 344    /// Bright terminal foreground color.
 345    #[serde(rename = "terminal.bright_foreground")]
 346    pub terminal_bright_foreground: Option<String>,
 347
 348    /// Dim terminal foreground color.
 349    #[serde(rename = "terminal.dim_foreground")]
 350    pub terminal_dim_foreground: Option<String>,
 351
 352    /// Black ANSI terminal color.
 353    #[serde(rename = "terminal.ansi.black")]
 354    pub terminal_ansi_black: Option<String>,
 355
 356    /// Bright black ANSI terminal color.
 357    #[serde(rename = "terminal.ansi.bright_black")]
 358    pub terminal_ansi_bright_black: Option<String>,
 359
 360    /// Dim black ANSI terminal color.
 361    #[serde(rename = "terminal.ansi.dim_black")]
 362    pub terminal_ansi_dim_black: Option<String>,
 363
 364    /// Red ANSI terminal color.
 365    #[serde(rename = "terminal.ansi.red")]
 366    pub terminal_ansi_red: Option<String>,
 367
 368    /// Bright red ANSI terminal color.
 369    #[serde(rename = "terminal.ansi.bright_red")]
 370    pub terminal_ansi_bright_red: Option<String>,
 371
 372    /// Dim red ANSI terminal color.
 373    #[serde(rename = "terminal.ansi.dim_red")]
 374    pub terminal_ansi_dim_red: Option<String>,
 375
 376    /// Green ANSI terminal color.
 377    #[serde(rename = "terminal.ansi.green")]
 378    pub terminal_ansi_green: Option<String>,
 379
 380    /// Bright green ANSI terminal color.
 381    #[serde(rename = "terminal.ansi.bright_green")]
 382    pub terminal_ansi_bright_green: Option<String>,
 383
 384    /// Dim green ANSI terminal color.
 385    #[serde(rename = "terminal.ansi.dim_green")]
 386    pub terminal_ansi_dim_green: Option<String>,
 387
 388    /// Yellow ANSI terminal color.
 389    #[serde(rename = "terminal.ansi.yellow")]
 390    pub terminal_ansi_yellow: Option<String>,
 391
 392    /// Bright yellow ANSI terminal color.
 393    #[serde(rename = "terminal.ansi.bright_yellow")]
 394    pub terminal_ansi_bright_yellow: Option<String>,
 395
 396    /// Dim yellow ANSI terminal color.
 397    #[serde(rename = "terminal.ansi.dim_yellow")]
 398    pub terminal_ansi_dim_yellow: Option<String>,
 399
 400    /// Blue ANSI terminal color.
 401    #[serde(rename = "terminal.ansi.blue")]
 402    pub terminal_ansi_blue: Option<String>,
 403
 404    /// Bright blue ANSI terminal color.
 405    #[serde(rename = "terminal.ansi.bright_blue")]
 406    pub terminal_ansi_bright_blue: Option<String>,
 407
 408    /// Dim blue ANSI terminal color.
 409    #[serde(rename = "terminal.ansi.dim_blue")]
 410    pub terminal_ansi_dim_blue: Option<String>,
 411
 412    /// Magenta ANSI terminal color.
 413    #[serde(rename = "terminal.ansi.magenta")]
 414    pub terminal_ansi_magenta: Option<String>,
 415
 416    /// Bright magenta ANSI terminal color.
 417    #[serde(rename = "terminal.ansi.bright_magenta")]
 418    pub terminal_ansi_bright_magenta: Option<String>,
 419
 420    /// Dim magenta ANSI terminal color.
 421    #[serde(rename = "terminal.ansi.dim_magenta")]
 422    pub terminal_ansi_dim_magenta: Option<String>,
 423
 424    /// Cyan ANSI terminal color.
 425    #[serde(rename = "terminal.ansi.cyan")]
 426    pub terminal_ansi_cyan: Option<String>,
 427
 428    /// Bright cyan ANSI terminal color.
 429    #[serde(rename = "terminal.ansi.bright_cyan")]
 430    pub terminal_ansi_bright_cyan: Option<String>,
 431
 432    /// Dim cyan ANSI terminal color.
 433    #[serde(rename = "terminal.ansi.dim_cyan")]
 434    pub terminal_ansi_dim_cyan: Option<String>,
 435
 436    /// White ANSI terminal color.
 437    #[serde(rename = "terminal.ansi.white")]
 438    pub terminal_ansi_white: Option<String>,
 439
 440    /// Bright white ANSI terminal color.
 441    #[serde(rename = "terminal.ansi.bright_white")]
 442    pub terminal_ansi_bright_white: Option<String>,
 443
 444    /// Dim white ANSI terminal color.
 445    #[serde(rename = "terminal.ansi.dim_white")]
 446    pub terminal_ansi_dim_white: Option<String>,
 447
 448    #[serde(rename = "link_text.hover")]
 449    pub link_text_hover: Option<String>,
 450}
 451
 452impl ThemeColorsContent {
 453    /// Returns a [`ThemeColorsRefinement`] based on the colors in the [`ThemeColorsContent`].
 454    pub fn theme_colors_refinement(&self) -> ThemeColorsRefinement {
 455        ThemeColorsRefinement {
 456            border: self
 457                .border
 458                .as_ref()
 459                .and_then(|color| try_parse_color(&color).ok()),
 460            border_variant: self
 461                .border_variant
 462                .as_ref()
 463                .and_then(|color| try_parse_color(&color).ok()),
 464            border_focused: self
 465                .border_focused
 466                .as_ref()
 467                .and_then(|color| try_parse_color(&color).ok()),
 468            border_selected: self
 469                .border_selected
 470                .as_ref()
 471                .and_then(|color| try_parse_color(&color).ok()),
 472            border_transparent: self
 473                .border_transparent
 474                .as_ref()
 475                .and_then(|color| try_parse_color(&color).ok()),
 476            border_disabled: self
 477                .border_disabled
 478                .as_ref()
 479                .and_then(|color| try_parse_color(&color).ok()),
 480            elevated_surface_background: self
 481                .elevated_surface_background
 482                .as_ref()
 483                .and_then(|color| try_parse_color(&color).ok()),
 484            surface_background: self
 485                .surface_background
 486                .as_ref()
 487                .and_then(|color| try_parse_color(&color).ok()),
 488            background: self
 489                .background
 490                .as_ref()
 491                .and_then(|color| try_parse_color(&color).ok()),
 492            element_background: self
 493                .element_background
 494                .as_ref()
 495                .and_then(|color| try_parse_color(&color).ok()),
 496            element_hover: self
 497                .element_hover
 498                .as_ref()
 499                .and_then(|color| try_parse_color(&color).ok()),
 500            element_active: self
 501                .element_active
 502                .as_ref()
 503                .and_then(|color| try_parse_color(&color).ok()),
 504            element_selected: self
 505                .element_selected
 506                .as_ref()
 507                .and_then(|color| try_parse_color(&color).ok()),
 508            element_disabled: self
 509                .element_disabled
 510                .as_ref()
 511                .and_then(|color| try_parse_color(&color).ok()),
 512            drop_target_background: self
 513                .drop_target_background
 514                .as_ref()
 515                .and_then(|color| try_parse_color(&color).ok()),
 516            ghost_element_background: self
 517                .ghost_element_background
 518                .as_ref()
 519                .and_then(|color| try_parse_color(&color).ok()),
 520            ghost_element_hover: self
 521                .ghost_element_hover
 522                .as_ref()
 523                .and_then(|color| try_parse_color(&color).ok()),
 524            ghost_element_active: self
 525                .ghost_element_active
 526                .as_ref()
 527                .and_then(|color| try_parse_color(&color).ok()),
 528            ghost_element_selected: self
 529                .ghost_element_selected
 530                .as_ref()
 531                .and_then(|color| try_parse_color(&color).ok()),
 532            ghost_element_disabled: self
 533                .ghost_element_disabled
 534                .as_ref()
 535                .and_then(|color| try_parse_color(&color).ok()),
 536            text: self
 537                .text
 538                .as_ref()
 539                .and_then(|color| try_parse_color(&color).ok()),
 540            text_muted: self
 541                .text_muted
 542                .as_ref()
 543                .and_then(|color| try_parse_color(&color).ok()),
 544            text_placeholder: self
 545                .text_placeholder
 546                .as_ref()
 547                .and_then(|color| try_parse_color(&color).ok()),
 548            text_disabled: self
 549                .text_disabled
 550                .as_ref()
 551                .and_then(|color| try_parse_color(&color).ok()),
 552            text_accent: self
 553                .text_accent
 554                .as_ref()
 555                .and_then(|color| try_parse_color(&color).ok()),
 556            icon: self
 557                .icon
 558                .as_ref()
 559                .and_then(|color| try_parse_color(&color).ok()),
 560            icon_muted: self
 561                .icon_muted
 562                .as_ref()
 563                .and_then(|color| try_parse_color(&color).ok()),
 564            icon_disabled: self
 565                .icon_disabled
 566                .as_ref()
 567                .and_then(|color| try_parse_color(&color).ok()),
 568            icon_placeholder: self
 569                .icon_placeholder
 570                .as_ref()
 571                .and_then(|color| try_parse_color(&color).ok()),
 572            icon_accent: self
 573                .icon_accent
 574                .as_ref()
 575                .and_then(|color| try_parse_color(&color).ok()),
 576            status_bar_background: self
 577                .status_bar_background
 578                .as_ref()
 579                .and_then(|color| try_parse_color(&color).ok()),
 580            title_bar_background: self
 581                .title_bar_background
 582                .as_ref()
 583                .and_then(|color| try_parse_color(&color).ok()),
 584            toolbar_background: self
 585                .toolbar_background
 586                .as_ref()
 587                .and_then(|color| try_parse_color(&color).ok()),
 588            tab_bar_background: self
 589                .tab_bar_background
 590                .as_ref()
 591                .and_then(|color| try_parse_color(&color).ok()),
 592            tab_inactive_background: self
 593                .tab_inactive_background
 594                .as_ref()
 595                .and_then(|color| try_parse_color(&color).ok()),
 596            tab_active_background: self
 597                .tab_active_background
 598                .as_ref()
 599                .and_then(|color| try_parse_color(&color).ok()),
 600            search_match_background: self
 601                .search_match_background
 602                .as_ref()
 603                .and_then(|color| try_parse_color(&color).ok()),
 604            panel_background: self
 605                .panel_background
 606                .as_ref()
 607                .and_then(|color| try_parse_color(&color).ok()),
 608            panel_focused_border: self
 609                .panel_focused_border
 610                .as_ref()
 611                .and_then(|color| try_parse_color(&color).ok()),
 612            pane_focused_border: self
 613                .pane_focused_border
 614                .as_ref()
 615                .and_then(|color| try_parse_color(&color).ok()),
 616            scrollbar_thumb_background: self
 617                .scrollbar_thumb_background
 618                .as_ref()
 619                .and_then(|color| try_parse_color(&color).ok()),
 620            scrollbar_thumb_hover_background: self
 621                .scrollbar_thumb_hover_background
 622                .as_ref()
 623                .and_then(|color| try_parse_color(&color).ok()),
 624            scrollbar_thumb_border: self
 625                .scrollbar_thumb_border
 626                .as_ref()
 627                .and_then(|color| try_parse_color(&color).ok()),
 628            scrollbar_track_background: self
 629                .scrollbar_track_background
 630                .as_ref()
 631                .and_then(|color| try_parse_color(&color).ok()),
 632            scrollbar_track_border: self
 633                .scrollbar_track_border
 634                .as_ref()
 635                .and_then(|color| try_parse_color(&color).ok()),
 636            editor_foreground: self
 637                .editor_foreground
 638                .as_ref()
 639                .and_then(|color| try_parse_color(&color).ok()),
 640            editor_background: self
 641                .editor_background
 642                .as_ref()
 643                .and_then(|color| try_parse_color(&color).ok()),
 644            editor_gutter_background: self
 645                .editor_gutter_background
 646                .as_ref()
 647                .and_then(|color| try_parse_color(&color).ok()),
 648            editor_subheader_background: self
 649                .editor_subheader_background
 650                .as_ref()
 651                .and_then(|color| try_parse_color(&color).ok()),
 652            editor_active_line_background: self
 653                .editor_active_line_background
 654                .as_ref()
 655                .and_then(|color| try_parse_color(&color).ok()),
 656            editor_highlighted_line_background: self
 657                .editor_highlighted_line_background
 658                .as_ref()
 659                .and_then(|color| try_parse_color(&color).ok()),
 660            editor_line_number: self
 661                .editor_line_number
 662                .as_ref()
 663                .and_then(|color| try_parse_color(&color).ok()),
 664            editor_active_line_number: self
 665                .editor_active_line_number
 666                .as_ref()
 667                .and_then(|color| try_parse_color(&color).ok()),
 668            editor_invisible: self
 669                .editor_invisible
 670                .as_ref()
 671                .and_then(|color| try_parse_color(&color).ok()),
 672            editor_wrap_guide: self
 673                .editor_wrap_guide
 674                .as_ref()
 675                .and_then(|color| try_parse_color(&color).ok()),
 676            editor_active_wrap_guide: self
 677                .editor_active_wrap_guide
 678                .as_ref()
 679                .and_then(|color| try_parse_color(&color).ok()),
 680            editor_document_highlight_read_background: self
 681                .editor_document_highlight_read_background
 682                .as_ref()
 683                .and_then(|color| try_parse_color(&color).ok()),
 684            editor_document_highlight_write_background: self
 685                .editor_document_highlight_write_background
 686                .as_ref()
 687                .and_then(|color| try_parse_color(&color).ok()),
 688            terminal_background: self
 689                .terminal_background
 690                .as_ref()
 691                .and_then(|color| try_parse_color(&color).ok()),
 692            terminal_foreground: self
 693                .terminal_foreground
 694                .as_ref()
 695                .and_then(|color| try_parse_color(&color).ok()),
 696            terminal_bright_foreground: self
 697                .terminal_bright_foreground
 698                .as_ref()
 699                .and_then(|color| try_parse_color(&color).ok()),
 700            terminal_dim_foreground: self
 701                .terminal_dim_foreground
 702                .as_ref()
 703                .and_then(|color| try_parse_color(&color).ok()),
 704            terminal_ansi_black: self
 705                .terminal_ansi_black
 706                .as_ref()
 707                .and_then(|color| try_parse_color(&color).ok()),
 708            terminal_ansi_bright_black: self
 709                .terminal_ansi_bright_black
 710                .as_ref()
 711                .and_then(|color| try_parse_color(&color).ok()),
 712            terminal_ansi_dim_black: self
 713                .terminal_ansi_dim_black
 714                .as_ref()
 715                .and_then(|color| try_parse_color(&color).ok()),
 716            terminal_ansi_red: self
 717                .terminal_ansi_red
 718                .as_ref()
 719                .and_then(|color| try_parse_color(&color).ok()),
 720            terminal_ansi_bright_red: self
 721                .terminal_ansi_bright_red
 722                .as_ref()
 723                .and_then(|color| try_parse_color(&color).ok()),
 724            terminal_ansi_dim_red: self
 725                .terminal_ansi_dim_red
 726                .as_ref()
 727                .and_then(|color| try_parse_color(&color).ok()),
 728            terminal_ansi_green: self
 729                .terminal_ansi_green
 730                .as_ref()
 731                .and_then(|color| try_parse_color(&color).ok()),
 732            terminal_ansi_bright_green: self
 733                .terminal_ansi_bright_green
 734                .as_ref()
 735                .and_then(|color| try_parse_color(&color).ok()),
 736            terminal_ansi_dim_green: self
 737                .terminal_ansi_dim_green
 738                .as_ref()
 739                .and_then(|color| try_parse_color(&color).ok()),
 740            terminal_ansi_yellow: self
 741                .terminal_ansi_yellow
 742                .as_ref()
 743                .and_then(|color| try_parse_color(&color).ok()),
 744            terminal_ansi_bright_yellow: self
 745                .terminal_ansi_bright_yellow
 746                .as_ref()
 747                .and_then(|color| try_parse_color(&color).ok()),
 748            terminal_ansi_dim_yellow: self
 749                .terminal_ansi_dim_yellow
 750                .as_ref()
 751                .and_then(|color| try_parse_color(&color).ok()),
 752            terminal_ansi_blue: self
 753                .terminal_ansi_blue
 754                .as_ref()
 755                .and_then(|color| try_parse_color(&color).ok()),
 756            terminal_ansi_bright_blue: self
 757                .terminal_ansi_bright_blue
 758                .as_ref()
 759                .and_then(|color| try_parse_color(&color).ok()),
 760            terminal_ansi_dim_blue: self
 761                .terminal_ansi_dim_blue
 762                .as_ref()
 763                .and_then(|color| try_parse_color(&color).ok()),
 764            terminal_ansi_magenta: self
 765                .terminal_ansi_magenta
 766                .as_ref()
 767                .and_then(|color| try_parse_color(&color).ok()),
 768            terminal_ansi_bright_magenta: self
 769                .terminal_ansi_bright_magenta
 770                .as_ref()
 771                .and_then(|color| try_parse_color(&color).ok()),
 772            terminal_ansi_dim_magenta: self
 773                .terminal_ansi_dim_magenta
 774                .as_ref()
 775                .and_then(|color| try_parse_color(&color).ok()),
 776            terminal_ansi_cyan: self
 777                .terminal_ansi_cyan
 778                .as_ref()
 779                .and_then(|color| try_parse_color(&color).ok()),
 780            terminal_ansi_bright_cyan: self
 781                .terminal_ansi_bright_cyan
 782                .as_ref()
 783                .and_then(|color| try_parse_color(&color).ok()),
 784            terminal_ansi_dim_cyan: self
 785                .terminal_ansi_dim_cyan
 786                .as_ref()
 787                .and_then(|color| try_parse_color(&color).ok()),
 788            terminal_ansi_white: self
 789                .terminal_ansi_white
 790                .as_ref()
 791                .and_then(|color| try_parse_color(&color).ok()),
 792            terminal_ansi_bright_white: self
 793                .terminal_ansi_bright_white
 794                .as_ref()
 795                .and_then(|color| try_parse_color(&color).ok()),
 796            terminal_ansi_dim_white: self
 797                .terminal_ansi_dim_white
 798                .as_ref()
 799                .and_then(|color| try_parse_color(&color).ok()),
 800            link_text_hover: self
 801                .link_text_hover
 802                .as_ref()
 803                .and_then(|color| try_parse_color(&color).ok()),
 804        }
 805    }
 806}
 807
 808#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
 809#[serde(default)]
 810pub struct StatusColorsContent {
 811    /// Indicates some kind of conflict, like a file changed on disk while it was open, or
 812    /// merge conflicts in a Git repository.
 813    #[serde(rename = "conflict")]
 814    pub conflict: Option<String>,
 815
 816    #[serde(rename = "conflict.background")]
 817    pub conflict_background: Option<String>,
 818
 819    #[serde(rename = "conflict.border")]
 820    pub conflict_border: Option<String>,
 821
 822    /// Indicates something new, like a new file added to a Git repository.
 823    #[serde(rename = "created")]
 824    pub created: Option<String>,
 825
 826    #[serde(rename = "created.background")]
 827    pub created_background: Option<String>,
 828
 829    #[serde(rename = "created.border")]
 830    pub created_border: Option<String>,
 831
 832    /// Indicates that something no longer exists, like a deleted file.
 833    #[serde(rename = "deleted")]
 834    pub deleted: Option<String>,
 835
 836    #[serde(rename = "deleted.background")]
 837    pub deleted_background: Option<String>,
 838
 839    #[serde(rename = "deleted.border")]
 840    pub deleted_border: Option<String>,
 841
 842    /// Indicates a system error, a failed operation or a diagnostic error.
 843    #[serde(rename = "error")]
 844    pub error: Option<String>,
 845
 846    #[serde(rename = "error.background")]
 847    pub error_background: Option<String>,
 848
 849    #[serde(rename = "error.border")]
 850    pub error_border: Option<String>,
 851
 852    /// Represents a hidden status, such as a file being hidden in a file tree.
 853    #[serde(rename = "hidden")]
 854    pub hidden: Option<String>,
 855
 856    #[serde(rename = "hidden.background")]
 857    pub hidden_background: Option<String>,
 858
 859    #[serde(rename = "hidden.border")]
 860    pub hidden_border: Option<String>,
 861
 862    /// Indicates a hint or some kind of additional information.
 863    #[serde(rename = "hint")]
 864    pub hint: Option<String>,
 865
 866    #[serde(rename = "hint.background")]
 867    pub hint_background: Option<String>,
 868
 869    #[serde(rename = "hint.border")]
 870    pub hint_border: Option<String>,
 871
 872    /// Indicates that something is deliberately ignored, such as a file or operation ignored by Git.
 873    #[serde(rename = "ignored")]
 874    pub ignored: Option<String>,
 875
 876    #[serde(rename = "ignored.background")]
 877    pub ignored_background: Option<String>,
 878
 879    #[serde(rename = "ignored.border")]
 880    pub ignored_border: Option<String>,
 881
 882    /// Represents informational status updates or messages.
 883    #[serde(rename = "info")]
 884    pub info: Option<String>,
 885
 886    #[serde(rename = "info.background")]
 887    pub info_background: Option<String>,
 888
 889    #[serde(rename = "info.border")]
 890    pub info_border: Option<String>,
 891
 892    /// Indicates a changed or altered status, like a file that has been edited.
 893    #[serde(rename = "modified")]
 894    pub modified: Option<String>,
 895
 896    #[serde(rename = "modified.background")]
 897    pub modified_background: Option<String>,
 898
 899    #[serde(rename = "modified.border")]
 900    pub modified_border: Option<String>,
 901
 902    /// Indicates something that is predicted, like automatic code completion, or generated code.
 903    #[serde(rename = "predictive")]
 904    pub predictive: Option<String>,
 905
 906    #[serde(rename = "predictive.background")]
 907    pub predictive_background: Option<String>,
 908
 909    #[serde(rename = "predictive.border")]
 910    pub predictive_border: Option<String>,
 911
 912    /// Represents a renamed status, such as a file that has been renamed.
 913    #[serde(rename = "renamed")]
 914    pub renamed: Option<String>,
 915
 916    #[serde(rename = "renamed.background")]
 917    pub renamed_background: Option<String>,
 918
 919    #[serde(rename = "renamed.border")]
 920    pub renamed_border: Option<String>,
 921
 922    /// Indicates a successful operation or task completion.
 923    #[serde(rename = "success")]
 924    pub success: Option<String>,
 925
 926    #[serde(rename = "success.background")]
 927    pub success_background: Option<String>,
 928
 929    #[serde(rename = "success.border")]
 930    pub success_border: Option<String>,
 931
 932    /// Indicates some kind of unreachable status, like a block of code that can never be reached.
 933    #[serde(rename = "unreachable")]
 934    pub unreachable: Option<String>,
 935
 936    #[serde(rename = "unreachable.background")]
 937    pub unreachable_background: Option<String>,
 938
 939    #[serde(rename = "unreachable.border")]
 940    pub unreachable_border: Option<String>,
 941
 942    /// Represents a warning status, like an operation that is about to fail.
 943    #[serde(rename = "warning")]
 944    pub warning: Option<String>,
 945
 946    #[serde(rename = "warning.background")]
 947    pub warning_background: Option<String>,
 948
 949    #[serde(rename = "warning.border")]
 950    pub warning_border: Option<String>,
 951}
 952
 953impl StatusColorsContent {
 954    /// Returns a [`StatusColorsRefinement`] based on the colors in the [`StatusColorsContent`].
 955    pub fn status_colors_refinement(&self) -> StatusColorsRefinement {
 956        StatusColorsRefinement {
 957            conflict: self
 958                .conflict
 959                .as_ref()
 960                .and_then(|color| try_parse_color(&color).ok()),
 961            conflict_background: self
 962                .conflict_background
 963                .as_ref()
 964                .and_then(|color| try_parse_color(&color).ok()),
 965            conflict_border: self
 966                .conflict_border
 967                .as_ref()
 968                .and_then(|color| try_parse_color(&color).ok()),
 969            created: self
 970                .created
 971                .as_ref()
 972                .and_then(|color| try_parse_color(&color).ok()),
 973            created_background: self
 974                .created_background
 975                .as_ref()
 976                .and_then(|color| try_parse_color(&color).ok()),
 977            created_border: self
 978                .created_border
 979                .as_ref()
 980                .and_then(|color| try_parse_color(&color).ok()),
 981            deleted: self
 982                .deleted
 983                .as_ref()
 984                .and_then(|color| try_parse_color(&color).ok()),
 985            deleted_background: self
 986                .deleted_background
 987                .as_ref()
 988                .and_then(|color| try_parse_color(&color).ok()),
 989            deleted_border: self
 990                .deleted_border
 991                .as_ref()
 992                .and_then(|color| try_parse_color(&color).ok()),
 993            error: self
 994                .error
 995                .as_ref()
 996                .and_then(|color| try_parse_color(&color).ok()),
 997            error_background: self
 998                .error_background
 999                .as_ref()
1000                .and_then(|color| try_parse_color(&color).ok()),
1001            error_border: self
1002                .error_border
1003                .as_ref()
1004                .and_then(|color| try_parse_color(&color).ok()),
1005            hidden: self
1006                .hidden
1007                .as_ref()
1008                .and_then(|color| try_parse_color(&color).ok()),
1009            hidden_background: self
1010                .hidden_background
1011                .as_ref()
1012                .and_then(|color| try_parse_color(&color).ok()),
1013            hidden_border: self
1014                .hidden_border
1015                .as_ref()
1016                .and_then(|color| try_parse_color(&color).ok()),
1017            hint: self
1018                .hint
1019                .as_ref()
1020                .and_then(|color| try_parse_color(&color).ok()),
1021            hint_background: self
1022                .hint_background
1023                .as_ref()
1024                .and_then(|color| try_parse_color(&color).ok()),
1025            hint_border: self
1026                .hint_border
1027                .as_ref()
1028                .and_then(|color| try_parse_color(&color).ok()),
1029            ignored: self
1030                .ignored
1031                .as_ref()
1032                .and_then(|color| try_parse_color(&color).ok()),
1033            ignored_background: self
1034                .ignored_background
1035                .as_ref()
1036                .and_then(|color| try_parse_color(&color).ok()),
1037            ignored_border: self
1038                .ignored_border
1039                .as_ref()
1040                .and_then(|color| try_parse_color(&color).ok()),
1041            info: self
1042                .info
1043                .as_ref()
1044                .and_then(|color| try_parse_color(&color).ok()),
1045            info_background: self
1046                .info_background
1047                .as_ref()
1048                .and_then(|color| try_parse_color(&color).ok()),
1049            info_border: self
1050                .info_border
1051                .as_ref()
1052                .and_then(|color| try_parse_color(&color).ok()),
1053            modified: self
1054                .modified
1055                .as_ref()
1056                .and_then(|color| try_parse_color(&color).ok()),
1057            modified_background: self
1058                .modified_background
1059                .as_ref()
1060                .and_then(|color| try_parse_color(&color).ok()),
1061            modified_border: self
1062                .modified_border
1063                .as_ref()
1064                .and_then(|color| try_parse_color(&color).ok()),
1065            predictive: self
1066                .predictive
1067                .as_ref()
1068                .and_then(|color| try_parse_color(&color).ok()),
1069            predictive_background: self
1070                .predictive_background
1071                .as_ref()
1072                .and_then(|color| try_parse_color(&color).ok()),
1073            predictive_border: self
1074                .predictive_border
1075                .as_ref()
1076                .and_then(|color| try_parse_color(&color).ok()),
1077            renamed: self
1078                .renamed
1079                .as_ref()
1080                .and_then(|color| try_parse_color(&color).ok()),
1081            renamed_background: self
1082                .renamed_background
1083                .as_ref()
1084                .and_then(|color| try_parse_color(&color).ok()),
1085            renamed_border: self
1086                .renamed_border
1087                .as_ref()
1088                .and_then(|color| try_parse_color(&color).ok()),
1089            success: self
1090                .success
1091                .as_ref()
1092                .and_then(|color| try_parse_color(&color).ok()),
1093            success_background: self
1094                .success_background
1095                .as_ref()
1096                .and_then(|color| try_parse_color(&color).ok()),
1097            success_border: self
1098                .success_border
1099                .as_ref()
1100                .and_then(|color| try_parse_color(&color).ok()),
1101            unreachable: self
1102                .unreachable
1103                .as_ref()
1104                .and_then(|color| try_parse_color(&color).ok()),
1105            unreachable_background: self
1106                .unreachable_background
1107                .as_ref()
1108                .and_then(|color| try_parse_color(&color).ok()),
1109            unreachable_border: self
1110                .unreachable_border
1111                .as_ref()
1112                .and_then(|color| try_parse_color(&color).ok()),
1113            warning: self
1114                .warning
1115                .as_ref()
1116                .and_then(|color| try_parse_color(&color).ok()),
1117            warning_background: self
1118                .warning_background
1119                .as_ref()
1120                .and_then(|color| try_parse_color(&color).ok()),
1121            warning_border: self
1122                .warning_border
1123                .as_ref()
1124                .and_then(|color| try_parse_color(&color).ok()),
1125        }
1126    }
1127}
1128
1129#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
1130#[serde(default)]
1131pub struct HighlightStyleContent {
1132    pub color: Option<String>,
1133}