leetcode_tui_config/theme/
style.rs

1use ratatui::style::Modifier;
2use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};
3
4use super::color::Color;
5
6#[derive(Clone, Copy, Deserialize, Debug)]
7#[serde(from = "StyleShadow")]
8pub struct Style {
9    pub fg: Option<Color>,
10    pub bg: Option<Color>,
11    pub modifier: Modifier,
12}
13
14impl Serialize for Style {
15    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        let mut map = serializer.serialize_map(Some(3))?;
20        map.serialize_entry("fg", &self.fg)?;
21        map.serialize_entry("bg", &self.bg)?;
22        map.serialize_entry("modifier", &self.modifier.bits())?;
23        map.end()
24    }
25}
26
27impl From<Style> for ratatui::style::Style {
28    fn from(value: Style) -> Self {
29        ratatui::style::Style {
30            fg: value.fg.map(Into::into),
31            bg: value.bg.map(Into::into),
32            underline_color: None,
33            add_modifier: value.modifier,
34            sub_modifier: Modifier::empty(),
35        }
36    }
37}
38
39#[derive(Deserialize)]
40pub(super) struct StyleShadow {
41    #[serde(default)]
42    pub(super) fg: Option<Color>,
43    #[serde(default)]
44    pub(super) bg: Option<Color>,
45    #[serde(default)]
46    pub(super) bold: bool,
47    #[serde(default)]
48    pub(super) dim: bool,
49    #[serde(default)]
50    pub(super) italic: bool,
51    #[serde(default)]
52    pub(super) underline: bool,
53    #[serde(default)]
54    pub(super) blink: bool,
55    #[serde(default)]
56    pub(super) blink_rapid: bool,
57    #[serde(default)]
58    pub(super) reversed: bool,
59    #[serde(default)]
60    pub(super) hidden: bool,
61    #[serde(default)]
62    pub(super) crossed: bool,
63}
64
65impl From<StyleShadow> for Style {
66    fn from(value: StyleShadow) -> Self {
67        let mut modifier = Modifier::empty();
68        if value.bold {
69            modifier |= Modifier::BOLD;
70        }
71        if value.dim {
72            modifier |= Modifier::DIM;
73        }
74        if value.italic {
75            modifier |= Modifier::ITALIC;
76        }
77        if value.underline {
78            modifier |= Modifier::UNDERLINED;
79        }
80        if value.blink {
81            modifier |= Modifier::SLOW_BLINK;
82        }
83        if value.blink_rapid {
84            modifier |= Modifier::RAPID_BLINK;
85        }
86        if value.reversed {
87            modifier |= Modifier::REVERSED;
88        }
89        if value.hidden {
90            modifier |= Modifier::HIDDEN;
91        }
92        if value.crossed {
93            modifier |= Modifier::CROSSED_OUT;
94        }
95
96        Self {
97            fg: value.fg,
98            bg: value.bg,
99            modifier,
100        }
101    }
102}