@@ -1,10 +1,11 @@
11use std::collections::HashMap;
22
3+use log::warn;
34use serde::{Deserialize, Deserializer};
45use toml::Value;
56
67#[cfg(feature = "term")]
7−pub use tui::style::{Color, Style};
8+pub use tui::style::{Color, Modifier, Style};
89
910// #[derive(Clone, Copy, PartialEq, Eq, Default, Hash)]
1011// pub struct Color {
@@ -115,6 +116,7 @@ impl<'de> Deserialize<'de> for Theme {
115116}
116117
117118fn parse_style(style: &mut Style, value: Value) {
119+ //TODO: alert user of parsing failures
118120 if let Value::Table(entries) = value {
119121 for (name, value) in entries {
120122 match name.as_str() {
@@ -128,6 +130,13 @@ fn parse_style(style: &mut Style, value: Value) {
128130 *style = style.bg(color);
129131 }
130132 }
133+ "modifiers" => {
134+ if let Value::Array(arr) = value {
135+ for modifier in arr.iter().filter_map(parse_modifier) {
136+ *style = style.add_modifier(modifier);
137+ }
138+ }
139+ }
131140 _ => (),
132141 }
133142 }
@@ -157,9 +166,34 @@ fn parse_color(value: Value) -> Option<Color> {
157166 if let Some((red, green, blue)) = hex_string_to_rgb(&s) {
158167 Some(Color::Rgb(red, green, blue))
159168 } else {
169+ warn!("malformed hexcode in theme: {}", s);
160170 None
161171 }
162172 } else {
173+ warn!("unrecognized value in theme: {}", value);
174+ None
175+ }
176+}
177+
178+fn parse_modifier(value: &Value) -> Option<Modifier> {
179+ if let Value::String(s) = value {
180+ match s.as_str() {
181+ "bold" => Some(Modifier::BOLD),
182+ "dim" => Some(Modifier::DIM),
183+ "italic" => Some(Modifier::ITALIC),
184+ "underlined" => Some(Modifier::UNDERLINED),
185+ "slow_blink" => Some(Modifier::SLOW_BLINK),
186+ "rapid_blink" => Some(Modifier::RAPID_BLINK),
187+ "reversed" => Some(Modifier::REVERSED),
188+ "hidden" => Some(Modifier::HIDDEN),
189+ "crossed_out" => Some(Modifier::CROSSED_OUT),
190+ _ => {
191+ warn!("unrecognized modifier in theme: {}", s);
192+ None
193+ }
194+ }
195+ } else {
196+ warn!("unrecognized modifier in theme: {}", value);
163197 None
164198 }
165199}
@@ -177,3 +211,39 @@ impl Theme {
177211 &self.scopes
178212 }
179213}
214+
215+#[test]
216+fn test_parse_style_string() {
217+ let fg = Value::String("#ffffff".to_string());
218+
219+ let mut style = Style::default();
220+ parse_style(&mut style, fg);
221+
222+ assert_eq!(style, Style::default().fg(Color::Rgb(255, 255, 255)));
223+}
224+
225+#[test]
226+fn test_parse_style_table() {
227+ let table = toml::toml! {
228+ "keyword" = {
229+ fg = "#ffffff",
230+ bg = "#000000",
231+ modifiers = ["bold"],
232+ }
233+ };
234+
235+ let mut style = Style::default();
236+ if let Value::Table(entries) = table {
237+ for (_name, value) in entries {
238+ parse_style(&mut style, value);
239+ }
240+ }
241+
242+ assert_eq!(
243+ style,
244+ Style::default()
245+ .fg(Color::Rgb(255, 255, 255))
246+ .bg(Color::Rgb(0, 0, 0))
247+ .add_modifier(Modifier::BOLD)
248+ );
249+}