summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Davis2023-01-24 17:07:46 +0000
committerMichael Davis2023-01-24 18:50:46 +0000
commit70887b7378d642226ad5102fbe601fecb225225c (patch)
tree2de7f9847388e8961e6228b07aa8e5a6d71e4bea
parentb3e9f6233a64bb08dcb87788d5ca54dd25f13a27 (diff)
Refactor toml::Value->Theme conversion
The `From<Value>` implementation for `Theme` converted the Value to a string and re-parsed the string to convert it to `HashMap<String, Value>` which feels a bit wasteful. This change uses the underlying `toml::map::Map` directly when the value is a table and warns about the unexpected `Value` shape otherwise. This is necessary because toml 0.6.0 changes the Display implementation for Value::Table so that the `to_string` no longer encodes the value as a Document, just a Value. So the parse of the Value fails to be decoded as a HashMap. The behavior for returning `Default::default` matches the previous code's behavior except that it did not warn when the input Value was failed to parse.
-rw-r--r--helix-view/src/theme.rs78
1 files changed, 39 insertions, 39 deletions
diff --git a/helix-view/src/theme.rs b/helix-view/src/theme.rs
index ead0b9fb..43d4a7a7 100644
--- a/helix-view/src/theme.rs
+++ b/helix-view/src/theme.rs
@@ -4,7 +4,7 @@ use std::{
str,
};
-use anyhow::{anyhow, Context, Result};
+use anyhow::{anyhow, Result};
use helix_core::hashmap;
use helix_loader::merge_toml_values;
use log::warn;
@@ -209,16 +209,18 @@ pub struct Theme {
impl From<Value> for Theme {
fn from(value: Value) -> Self {
- let values: Result<HashMap<String, Value>> =
- toml::from_str(&value.to_string()).context("Failed to load theme");
-
- let (styles, scopes, highlights) = build_theme_values(values);
-
- Self {
- styles,
- scopes,
- highlights,
- ..Default::default()
+ if let Value::Table(table) = value {
+ let (styles, scopes, highlights) = build_theme_values(table);
+
+ Self {
+ styles,
+ scopes,
+ highlights,
+ ..Default::default()
+ }
+ } else {
+ warn!("Expected theme TOML value to be a table, found {:?}", value);
+ Default::default()
}
}
}
@@ -228,9 +230,9 @@ impl<'de> Deserialize<'de> for Theme {
where
D: Deserializer<'de>,
{
- let values = HashMap::<String, Value>::deserialize(deserializer)?;
+ let values = Map::<String, Value>::deserialize(deserializer)?;
- let (styles, scopes, highlights) = build_theme_values(Ok(values));
+ let (styles, scopes, highlights) = build_theme_values(values);
Ok(Self {
styles,
@@ -242,39 +244,37 @@ impl<'de> Deserialize<'de> for Theme {
}
fn build_theme_values(
- values: Result<HashMap<String, Value>>,
+ mut values: Map<String, Value>,
) -> (HashMap<String, Style>, Vec<String>, Vec<Style>) {
let mut styles = HashMap::new();
let mut scopes = Vec::new();
let mut highlights = Vec::new();
- if let Ok(mut colors) = values {
- // TODO: alert user of parsing failures in editor
- let palette = colors
- .remove("palette")
- .map(|value| {
- ThemePalette::try_from(value).unwrap_or_else(|err| {
- warn!("{}", err);
- ThemePalette::default()
- })
- })
- .unwrap_or_default();
- // remove inherits from value to prevent errors
- let _ = colors.remove("inherits");
- styles.reserve(colors.len());
- scopes.reserve(colors.len());
- highlights.reserve(colors.len());
- for (name, style_value) in colors {
- let mut style = Style::default();
- if let Err(err) = palette.parse_style(&mut style, style_value) {
+ // TODO: alert user of parsing failures in editor
+ let palette = values
+ .remove("palette")
+ .map(|value| {
+ ThemePalette::try_from(value).unwrap_or_else(|err| {
warn!("{}", err);
- }
-
- // these are used both as UI and as highlights
- styles.insert(name.clone(), style);
- scopes.push(name);
- highlights.push(style);
+ ThemePalette::default()
+ })
+ })
+ .unwrap_or_default();
+ // remove inherits from value to prevent errors
+ let _ = values.remove("inherits");
+ styles.reserve(values.len());
+ scopes.reserve(values.len());
+ highlights.reserve(values.len());
+ for (name, style_value) in values {
+ let mut style = Style::default();
+ if let Err(err) = palette.parse_style(&mut style, style_value) {
+ warn!("{}", err);
}
+
+ // these are used both as UI and as highlights
+ styles.insert(name.clone(), style);
+ scopes.push(name);
+ highlights.push(style);
}
(styles, scopes, highlights)