leetcode_tui_config/theme/
style.rs1use 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}