From aaac4c3b43bbbb5085f0545ba95d16d0b2b8cf6f Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Wed, 14 Apr 2021 14:28:22 +0200 Subject: [PATCH] Add docs for json values and make value related names shorter --- docs/content/main/expression_language.md | 2 + src/app.rs | 6 +- src/config/element.rs | 20 ++--- src/config/eww_config.rs | 12 +-- src/config/mod.rs | 2 +- src/config/script_var.rs | 10 +-- src/eww_state.rs | 30 +++---- src/opts.rs | 8 +- src/script_var_handler.rs | 4 +- src/value/attr_value/attr_value.rs | 108 +++++++++++------------ src/value/attr_value/attr_value_expr.rs | 88 +++++++++--------- src/value/attr_value/parser.rs | 96 ++++++++++---------- src/value/primitive.rs | 44 ++++----- src/widgets/mod.rs | 2 +- src/widgets/widget_definitions.rs | 4 +- src/widgets/widget_node.rs | 8 +- 16 files changed, 223 insertions(+), 221 deletions(-) diff --git a/docs/content/main/expression_language.md b/docs/content/main/expression_language.md index 82604cc..53b3dd0 100644 --- a/docs/content/main/expression_language.md +++ b/docs/content/main/expression_language.md @@ -32,4 +32,6 @@ The expression language supports: - conditionals (`if condition then 'value' else 'other value'`) - numbers, strings, booleans and variable references (`12`, `'hi'`, `true`, `some_variable`) - strings can contain other expressions again: `'foo {{some_variable}} bar'` +- json access (`object.field`, `array[12]`, `object["field"]`) + - for this, the object/array value needs to refer to a variable that contains a valid json string. diff --git a/src/app.rs b/src/app.rs index af729ec..14cb8dc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3,7 +3,7 @@ use crate::{ config::{window_definition::WindowName, AnchorPoint, WindowStacking}, display_backend, eww_state, script_var_handler::*, - value::{Coords, NumWithUnit, PrimitiveValue, VarName}, + value::{Coords, NumWithUnit, PrimVal, VarName}, EwwPaths, }; use anyhow::*; @@ -41,7 +41,7 @@ pub type DaemonResponseReceiver = tokio::sync::mpsc::UnboundedReceiver), + UpdateVars(Vec<(VarName, PrimVal)>), ReloadConfigAndCss(DaemonResponseSender), UpdateConfig(config::EwwConfig), UpdateCss(String), @@ -193,7 +193,7 @@ impl App { gtk::main_quit(); } - fn update_state(&mut self, fieldname: VarName, value: PrimitiveValue) { + fn update_state(&mut self, fieldname: VarName, value: PrimVal) { self.eww_state.update_variable(fieldname, value) } diff --git a/src/config/element.rs b/src/config/element.rs index 1f2b1fc..6f37f8e 100644 --- a/src/config/element.rs +++ b/src/config/element.rs @@ -4,7 +4,7 @@ use regex::Regex; use std::ops::Range; use crate::{ - value::{AttrName, AttrValue}, + value::{AttrName, AttrVal}, with_text_pos_context, }; use maplit::hashmap; @@ -41,7 +41,7 @@ impl WidgetDefinition { pub struct WidgetUse { pub name: String, pub children: Vec, - pub attrs: HashMap, + pub attrs: HashMap, pub text_pos: Option, } @@ -67,7 +67,7 @@ impl WidgetUse { }; let text_pos = xml.text_pos(); let widget_use = match xml { - XmlNode::Text(text) => WidgetUse::simple_text(AttrValue::parse_string(&text.text())), + XmlNode::Text(text) => WidgetUse::simple_text(AttrVal::parse_string(&text.text())), XmlNode::Element(elem) => WidgetUse { name: elem.tag_name().to_owned(), children: with_text_pos_context! { elem => elem.children().map(WidgetUse::from_xml_node).collect::>()?}?, @@ -77,7 +77,7 @@ impl WidgetUse { .map(|attr| { ( AttrName(attr.name().to_owned()), - AttrValue::parse_string(&xml_ext::resolve_escaped_symbols(&attr.value())), + AttrVal::parse_string(&xml_ext::resolve_escaped_symbols(&attr.value())), ) }) .collect::>(), @@ -88,7 +88,7 @@ impl WidgetUse { Ok(widget_use.at_pos(text_pos)) } - pub fn simple_text(text: AttrValue) -> Self { + pub fn simple_text(text: AttrVal) -> Self { WidgetUse { name: "label".to_owned(), children: vec![], @@ -111,7 +111,7 @@ mod test { #[test] fn test_simple_text() { - let expected_attr_value = AttrValue::from_primitive("my text"); + let expected_attr_value = AttrVal::from_primitive("my text"); let widget = WidgetUse::simple_text(expected_attr_value.clone()); assert_eq!( widget, @@ -138,12 +138,12 @@ mod test { let expected = WidgetUse { name: "widget_name".to_owned(), attrs: hashmap! { - AttrName("attr1".to_owned()) => AttrValue::from_primitive("hi"), - AttrName("attr2".to_owned()) => AttrValue::from_primitive("12"), + AttrName("attr1".to_owned()) => AttrVal::from_primitive("hi"), + AttrName("attr2".to_owned()) => AttrVal::from_primitive("12"), }, children: vec![ WidgetUse::new("child_widget".to_owned(), Vec::new()), - WidgetUse::simple_text(AttrValue::from_primitive("foo".to_owned())), + WidgetUse::simple_text(AttrVal::from_primitive("foo".to_owned())), ], ..WidgetUse::default() }; @@ -165,7 +165,7 @@ mod test { size: Some((12, 20)), structure: WidgetUse { name: "layout".to_owned(), - children: vec![WidgetUse::simple_text(AttrValue::from_primitive("test"))], + children: vec![WidgetUse::simple_text(AttrVal::from_primitive("test"))], attrs: HashMap::new(), ..WidgetUse::default() }, diff --git a/src/config/eww_config.rs b/src/config/eww_config.rs index 0b9a0f5..0bc1491 100644 --- a/src/config/eww_config.rs +++ b/src/config/eww_config.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{ util, - value::{PrimitiveValue, VarName}, + value::{PrimVal, VarName}, }; use super::{ @@ -18,7 +18,7 @@ use std::path::PathBuf; pub struct EwwConfig { widgets: HashMap, windows: HashMap, - initial_variables: HashMap, + initial_variables: HashMap, script_vars: HashMap, pub filepath: PathBuf, } @@ -44,7 +44,7 @@ impl EwwConfig { } // TODO this is kinda ugly - pub fn generate_initial_state(&self) -> Result> { + pub fn generate_initial_state(&self) -> Result> { let mut vars = self.script_vars.iter().map(|var| Ok((var.0.clone(), var.1.initial_value()?))).collect::>>()?; vars.extend(self.initial_variables.clone()); @@ -73,7 +73,7 @@ impl EwwConfig { pub struct RawEwwConfig { widgets: HashMap, windows: HashMap, - initial_variables: HashMap, + initial_variables: HashMap, script_vars: HashMap, pub filepath: PathBuf, } @@ -181,14 +181,14 @@ impl RawEwwConfig { } } -fn parse_variables_block(xml: XmlElement) -> Result<(HashMap, HashMap)> { +fn parse_variables_block(xml: XmlElement) -> Result<(HashMap, HashMap)> { let mut normal_vars = HashMap::new(); let mut script_vars = HashMap::new(); for node in xml.child_elements() { match node.tag_name() { "var" => { let value = node.only_child().map(|c| c.as_text_or_sourcecode()).unwrap_or_else(|_| String::new()); - normal_vars.insert(VarName(node.attr("name")?.to_owned()), PrimitiveValue::from_string(value)); + normal_vars.insert(VarName(node.attr("name")?.to_owned()), PrimVal::from_string(value)); } "script-var" => { let script_var = ScriptVar::from_xml_element(node)?; diff --git a/src/config/mod.rs b/src/config/mod.rs index 6ef5988..d6d20b1 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,6 @@ use crate::{ util, - value::{PrimitiveValue, VarName}, + value::{PrimVal, VarName}, }; use anyhow::*; diff --git a/src/config/script_var.rs b/src/config/script_var.rs index 5e9a999..6ef6ede 100644 --- a/src/config/script_var.rs +++ b/src/config/script_var.rs @@ -14,7 +14,7 @@ pub struct PollScriptVar { } impl PollScriptVar { - pub fn run_once(&self) -> Result { + pub fn run_once(&self) -> Result { run_command(&self.command) } } @@ -39,12 +39,12 @@ impl ScriptVar { } } - pub fn initial_value(&self) -> Result { + pub fn initial_value(&self) -> Result { match self { ScriptVar::Poll(x) => { run_command(&x.command).with_context(|| format!("Failed to compute initial value for {}", &self.name())) } - ScriptVar::Tail(_) => Ok(PrimitiveValue::from_string(String::new())), + ScriptVar::Tail(_) => Ok(PrimVal::from_string(String::new())), } } @@ -63,9 +63,9 @@ impl ScriptVar { } /// Run a command and get the output -fn run_command(cmd: &str) -> Result { +fn run_command(cmd: &str) -> Result { log::debug!("Running command: {}", cmd); let output = String::from_utf8(Command::new("/bin/sh").arg("-c").arg(cmd).output()?.stdout)?; let output = output.trim_matches('\n'); - Ok(PrimitiveValue::from(output)) + Ok(PrimVal::from(output)) } diff --git a/src/eww_state.rs b/src/eww_state.rs index f32659f..cdb92ec 100644 --- a/src/eww_state.rs +++ b/src/eww_state.rs @@ -1,17 +1,17 @@ use crate::{ config::window_definition::WindowName, - value::{AttrName, AttrValueElement, VarName}, + value::{AttrName, AttrValElement, VarName}, }; use anyhow::*; use std::{collections::HashMap, sync::Arc}; -use crate::value::{AttrValue, PrimitiveValue}; +use crate::value::{AttrVal, PrimVal}; /// Handler that gets executed to apply the necessary parts of the eww state to /// a gtk widget. These are created and initialized in EwwState::resolve. pub struct StateChangeHandler { - func: Box) -> Result<()> + 'static>, - unresolved_values: HashMap, + func: Box) -> Result<()> + 'static>, + unresolved_values: HashMap, } impl StateChangeHandler { @@ -21,7 +21,7 @@ impl StateChangeHandler { /// Run the StateChangeHandler. /// [`state`] should be the global [EwwState::state]. - fn run_with_state(&self, state: &HashMap) { + fn run_with_state(&self, state: &HashMap) { let resolved_attrs = self .unresolved_values .clone() @@ -61,7 +61,7 @@ impl EwwWindowState { #[derive(Default)] pub struct EwwState { windows: HashMap, - variables_state: HashMap, + variables_state: HashMap, } impl std::fmt::Debug for EwwState { @@ -71,11 +71,11 @@ impl std::fmt::Debug for EwwState { } impl EwwState { - pub fn from_default_vars(defaults: HashMap) -> Self { + pub fn from_default_vars(defaults: HashMap) -> Self { EwwState { variables_state: defaults, ..EwwState::default() } } - pub fn get_variables(&self) -> &HashMap { + pub fn get_variables(&self) -> &HashMap { &self.variables_state } @@ -91,7 +91,7 @@ impl EwwState { /// Update the value of a variable, running all registered /// [StateChangeHandler]s. - pub fn update_variable(&mut self, key: VarName, value: PrimitiveValue) { + pub fn update_variable(&mut self, key: VarName, value: PrimVal) { self.variables_state.insert(key.clone(), value); // run all of the handlers @@ -103,27 +103,27 @@ impl EwwState { } /// Look up a single variable in the eww state, returning an `Err` when the value is not found. - pub fn lookup(&self, var_name: &VarName) -> Result<&PrimitiveValue> { + pub fn lookup(&self, var_name: &VarName) -> Result<&PrimVal> { self.variables_state.get(var_name).with_context(|| format!("Unknown variable '{}' referenced", var_name)) } /// resolves a value if possible, using the current eww_state. - pub fn resolve_once<'a>(&'a self, value: &'a AttrValue) -> Result { + pub fn resolve_once<'a>(&'a self, value: &'a AttrVal) -> Result { value .iter() .map(|element| match element { - AttrValueElement::Primitive(primitive) => Ok(primitive.clone()), - AttrValueElement::Expr(expr) => expr.clone().eval(&self.variables_state), + AttrValElement::Primitive(primitive) => Ok(primitive.clone()), + AttrValElement::Expr(expr) => expr.clone().eval(&self.variables_state), }) .collect() } /// Resolve takes a function that applies a set of fully resolved attribute /// values to it's gtk widget. - pub fn resolve) -> Result<()> + 'static + Clone>( + pub fn resolve) -> Result<()> + 'static + Clone>( &mut self, window_name: &WindowName, - required_attributes: HashMap, + required_attributes: HashMap, set_value: F, ) { let handler = StateChangeHandler { func: Box::new(set_value), unresolved_values: required_attributes }; diff --git a/src/opts.rs b/src/opts.rs index 10d648c..ba1f1fe 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -5,7 +5,7 @@ use structopt::StructOpt; use crate::{ app, config::{AnchorPoint, WindowName}, - value::{Coords, PrimitiveValue, VarName}, + value::{Coords, PrimVal, VarName}, }; /// Struct that gets generated from `RawOpt`. @@ -61,7 +61,7 @@ pub enum ActionWithServer { Update { /// variable_name="new_value"-pairs that will be updated #[structopt(parse(try_from_str = parse_var_update_arg))] - mappings: Vec<(VarName, PrimitiveValue)>, + mappings: Vec<(VarName, PrimVal)>, }, /// open a window @@ -138,11 +138,11 @@ impl From for Opt { } } -fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimitiveValue)> { +fn parse_var_update_arg(s: &str) -> Result<(VarName, PrimVal)> { let (name, value) = s .split_once('=') .with_context(|| format!("arguments must be in the shape `variable_name=\"new_value\"`, but got: {}", s))?; - Ok((name.into(), PrimitiveValue::from_string(value.to_owned()))) + Ok((name.into(), PrimVal::from_string(value.to_owned()))) } impl ActionWithServer { diff --git a/src/script_var_handler.rs b/src/script_var_handler.rs index abaf547..d867a2b 100644 --- a/src/script_var_handler.rs +++ b/src/script_var_handler.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::{ app, config, - value::{PrimitiveValue, VarName}, + value::{PrimVal, VarName}, }; use anyhow::*; use app::DaemonCommand; @@ -197,7 +197,7 @@ impl TailVarHandler { _ = handle.wait() => break, _ = cancellation_token.cancelled() => break, Ok(Some(line)) = stdout_lines.next_line() => { - let new_value = PrimitiveValue::from_string(line.to_owned()); + let new_value = PrimVal::from_string(line.to_owned()); evt_send.send(DaemonCommand::UpdateVars(vec![(var.name.to_owned(), new_value)]))?; } else => break, diff --git a/src/value/attr_value/attr_value.rs b/src/value/attr_value/attr_value.rs index afc0550..ac4423d 100644 --- a/src/value/attr_value/attr_value.rs +++ b/src/value/attr_value/attr_value.rs @@ -9,45 +9,45 @@ use super::super::*; /// This can be a primitive String that contains any amount of variable /// references, as would be generated by the string "foo {{var}} bar". #[derive(Serialize, Deserialize, Clone, PartialEq, derive_more::Into, derive_more::From, Default)] -pub struct AttrValue(Vec); +pub struct AttrVal(Vec); -impl fmt::Display for AttrValue { +impl fmt::Display for AttrVal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.iter().map(|x| format!("{}", x)).join("")) } } -impl fmt::Debug for AttrValue { +impl fmt::Debug for AttrVal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "AttrValue({:?})", self.0) } } -impl IntoIterator for AttrValue { +impl IntoIterator for AttrVal { type IntoIter = std::vec::IntoIter; - type Item = AttrValueElement; + type Item = AttrValElement; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } -impl FromIterator for AttrValue { - fn from_iter>(iter: T) -> Self { - AttrValue(iter.into_iter().collect()) +impl FromIterator for AttrVal { + fn from_iter>(iter: T) -> Self { + AttrVal(iter.into_iter().collect()) } } -impl AttrValue { - pub fn from_primitive>(v: T) -> Self { - AttrValue(vec![AttrValueElement::Primitive(v.into())]) +impl AttrVal { + pub fn from_primitive>(v: T) -> Self { + AttrVal(vec![AttrValElement::Primitive(v.into())]) } pub fn from_var_ref>(v: T) -> Self { - AttrValue(vec![AttrValueElement::Expr(AttrValueExpr::VarRef(v.into()))]) + AttrVal(vec![AttrValElement::Expr(AttrValExpr::VarRef(v.into()))]) } - pub fn iter(&self) -> std::slice::Iter { + pub fn iter(&self) -> std::slice::Iter { self.0.iter() } @@ -58,13 +58,13 @@ impl AttrValue { /// resolve partially. /// If a var-ref links to another var-ref, that other var-ref is used. /// If a referenced variable is not found in the given hashmap, returns the var-ref unchanged. - pub fn resolve_one_level(self, variables: &HashMap) -> AttrValue { + pub fn resolve_one_level(self, variables: &HashMap) -> AttrVal { self.into_iter() .map(|entry| match entry { - AttrValueElement::Expr(expr) => AttrValueElement::Expr(expr.map_terminals_into(|child_expr| match child_expr { - AttrValueExpr::VarRef(var_name) => match variables.get(&var_name) { - Some(value) => AttrValueExpr::Literal(value.clone()), - None => AttrValueExpr::VarRef(var_name), + AttrValElement::Expr(expr) => AttrValElement::Expr(expr.map_terminals_into(|child_expr| match child_expr { + AttrValExpr::VarRef(var_name) => match variables.get(&var_name) { + Some(value) => AttrValExpr::Literal(value.clone()), + None => AttrValExpr::VarRef(var_name), }, other => other, })), @@ -77,17 +77,17 @@ impl AttrValue { /// resolve fully. /// As the variables here have to be primitive values, /// this enforces that var-refs are not linking to other variables. - pub fn resolve_fully(self, variables: &HashMap) -> Result { + pub fn resolve_fully(self, variables: &HashMap) -> Result { self.into_iter() .map(|element| match element { - AttrValueElement::Primitive(x) => Ok(x), - AttrValueElement::Expr(expr) => expr.eval(variables), + AttrValElement::Primitive(x) => Ok(x), + AttrValElement::Expr(expr) => expr.eval(variables), }) .collect() } // TODO this could be a fancy Iterator implementation, ig - pub fn parse_string(s: &str) -> AttrValue { + pub fn parse_string(s: &str) -> AttrVal { let mut elements = Vec::new(); let mut cur_word = "".to_owned(); @@ -98,7 +98,7 @@ impl AttrValue { if c == '}' { curly_count -= 1; if curly_count == 0 { - elements.push(AttrValueElement::Expr(AttrValueExpr::parse(varref).unwrap())); + elements.push(AttrValElement::Expr(AttrValExpr::parse(varref).unwrap())); cur_varref = None } } else { @@ -109,7 +109,7 @@ impl AttrValue { curly_count += 1; if curly_count == 2 { if !cur_word.is_empty() { - elements.push(AttrValueElement::primitive(std::mem::take(&mut cur_word))); + elements.push(AttrValElement::primitive(std::mem::take(&mut cur_word))); } cur_varref = Some(String::new()) } @@ -122,52 +122,52 @@ impl AttrValue { } } if let Some(unfinished_varref) = cur_varref.take() { - elements.push(AttrValueElement::primitive(unfinished_varref)); + elements.push(AttrValElement::primitive(unfinished_varref)); } else if !cur_word.is_empty() { - elements.push(AttrValueElement::primitive(cur_word)); + elements.push(AttrValElement::primitive(cur_word)); } - AttrValue(elements) + AttrVal(elements) } } #[derive(Clone, PartialEq, Serialize, Deserialize)] -pub enum AttrValueElement { - Primitive(PrimitiveValue), - Expr(AttrValueExpr), +pub enum AttrValElement { + Primitive(PrimVal), + Expr(AttrValExpr), } -impl fmt::Display for AttrValueElement { +impl fmt::Display for AttrValElement { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - AttrValueElement::Primitive(x) => write!(f, "{}", x), - AttrValueElement::Expr(x) => write!(f, "{{{{{}}}}}", x), + AttrValElement::Primitive(x) => write!(f, "{}", x), + AttrValElement::Expr(x) => write!(f, "{{{{{}}}}}", x), } } } -impl fmt::Debug for AttrValueElement { +impl fmt::Debug for AttrValElement { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - AttrValueElement::Primitive(x) => write!(f, "Primitive({:?})", x), - AttrValueElement::Expr(x) => write!(f, "Expr({:?})", x), + AttrValElement::Primitive(x) => write!(f, "Primitive({:?})", x), + AttrValElement::Expr(x) => write!(f, "Expr({:?})", x), } } } -impl AttrValueElement { +impl AttrValElement { pub fn primitive(s: String) -> Self { - AttrValueElement::Primitive(PrimitiveValue::from_string(s)) + AttrValElement::Primitive(PrimVal::from_string(s)) } - pub fn as_expr(&self) -> Option<&AttrValueExpr> { + pub fn as_expr(&self) -> Option<&AttrValExpr> { match self { - AttrValueElement::Expr(x) => Some(&x), + AttrValElement::Expr(x) => Some(&x), _ => None, } } - pub fn as_primitive(&self) -> Option<&PrimitiveValue> { + pub fn as_primitive(&self) -> Option<&PrimVal> { match self { - AttrValueElement::Primitive(x) => Some(&x), + AttrValElement::Primitive(x) => Some(&x), _ => None, } } @@ -180,30 +180,30 @@ mod test { #[test] fn test_parse_string_or_var_ref_list() { let input = "{{foo}}{{bar}}b{}azb{a}z{{bat}}{}quok{{test}}"; - let output = AttrValue::parse_string(input); + let output = AttrVal::parse_string(input); assert_eq!( output, - AttrValue(vec![ - AttrValueElement::Expr(AttrValueExpr::VarRef(VarName("foo".to_owned()))), - AttrValueElement::Expr(AttrValueExpr::VarRef(VarName("bar".to_owned()))), - AttrValueElement::primitive("b{}azb{a}z".to_owned()), - AttrValueElement::Expr(AttrValueExpr::VarRef(VarName("bat".to_owned()))), - AttrValueElement::primitive("{}quok".to_owned()), - AttrValueElement::Expr(AttrValueExpr::VarRef(VarName("test".to_owned()))), + AttrVal(vec![ + AttrValElement::Expr(AttrValExpr::VarRef(VarName("foo".to_owned()))), + AttrValElement::Expr(AttrValExpr::VarRef(VarName("bar".to_owned()))), + AttrValElement::primitive("b{}azb{a}z".to_owned()), + AttrValElement::Expr(AttrValExpr::VarRef(VarName("bat".to_owned()))), + AttrValElement::primitive("{}quok".to_owned()), + AttrValElement::Expr(AttrValExpr::VarRef(VarName("test".to_owned()))), ]), ) } #[test] fn test_parse_string_with_var_refs_attr_value() { assert_eq!( - AttrValue( + AttrVal( vec![ - AttrValueElement::Expr(AttrValueExpr::VarRef(VarName("var".to_owned()))), - AttrValueElement::primitive("something".to_owned()) + AttrValElement::Expr(AttrValExpr::VarRef(VarName("var".to_owned()))), + AttrValElement::primitive("something".to_owned()) ] .into() ), - AttrValue::parse_string("{{var}}something") + AttrVal::parse_string("{{var}}something") ); } } diff --git a/src/value/attr_value/attr_value_expr.rs b/src/value/attr_value/attr_value_expr.rs index 770a806..0a4bca0 100644 --- a/src/value/attr_value/attr_value_expr.rs +++ b/src/value/attr_value/attr_value_expr.rs @@ -52,24 +52,24 @@ impl std::fmt::Display for UnaryOp { } #[derive(Clone, PartialEq, Serialize, Deserialize, Debug)] -pub enum AttrValueExpr { - Literal(AttrValue), +pub enum AttrValExpr { + Literal(AttrVal), VarRef(VarName), - BinOp(Box, BinOp, Box), - UnaryOp(UnaryOp, Box), - IfElse(Box, Box, Box), - JsonAccessIndex(Box, Box), + BinOp(Box, BinOp, Box), + UnaryOp(UnaryOp, Box), + IfElse(Box, Box, Box), + JsonAccess(Box, Box), } -impl std::fmt::Display for AttrValueExpr { +impl std::fmt::Display for AttrValExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AttrValueExpr::VarRef(x) => write!(f, "{}", x), - AttrValueExpr::Literal(x) => write!(f, "\"{}\"", x), - AttrValueExpr::BinOp(l, op, r) => write!(f, "({} {} {})", l, op, r), - AttrValueExpr::UnaryOp(op, x) => write!(f, "{}{}", op, x), - AttrValueExpr::IfElse(a, b, c) => write!(f, "(if {} then {} else {})", a, b, c), - AttrValueExpr::JsonAccessIndex(value, index) => write!(f, "{}[{}]", value, index), + AttrValExpr::VarRef(x) => write!(f, "{}", x), + AttrValExpr::Literal(x) => write!(f, "\"{}\"", x), + AttrValExpr::BinOp(l, op, r) => write!(f, "({} {} {})", l, op, r), + AttrValExpr::UnaryOp(op, x) => write!(f, "{}{}", op, x), + AttrValExpr::IfElse(a, b, c) => write!(f, "(if {} then {} else {})", a, b, c), + AttrValExpr::JsonAccess(value, index) => write!(f, "{}[{}]", value, index), } } } @@ -79,9 +79,9 @@ impl std::fmt::Display for AttrValueExpr { // write!(f, "{:?}", self) //} -impl AttrValueExpr { +impl AttrValExpr { pub fn map_terminals_into(self, f: impl Fn(Self) -> Self) -> Self { - use AttrValueExpr::*; + use AttrValExpr::*; match self { BinOp(box a, op, box b) => BinOp(box f(a), op, box f(b)), IfElse(box a, box b, box c) => IfElse(box f(a), box f(b), box f(c)), @@ -90,12 +90,12 @@ impl AttrValueExpr { } /// resolve variable references in the expression. Fails if a variable cannot be resolved. - pub fn resolve_refs(self, variables: &HashMap) -> Result { - use AttrValueExpr::*; + pub fn resolve_refs(self, variables: &HashMap) -> Result { + use AttrValExpr::*; match self { // Literal(x) => Ok(Literal(AttrValue::from_primitive(x.resolve_fully(&variables)?))), Literal(x) => Ok(Literal(x)), - VarRef(ref name) => Ok(Literal(AttrValue::from_primitive( + VarRef(ref name) => Ok(Literal(AttrVal::from_primitive( variables.get(name).with_context(|| format!("Unknown variable {} referenced in {:?}", &name, &self))?.clone(), ))), BinOp(box a, op, box b) => Ok(BinOp(box a.resolve_refs(variables)?, op, box b.resolve_refs(variables)?)), @@ -103,12 +103,12 @@ impl AttrValueExpr { IfElse(box a, box b, box c) => { Ok(IfElse(box a.resolve_refs(variables)?, box b.resolve_refs(variables)?, box c.resolve_refs(variables)?)) } - JsonAccessIndex(box a, box b) => Ok(JsonAccessIndex(box a.resolve_refs(variables)?, box b.resolve_refs(variables)?)), + JsonAccess(box a, box b) => Ok(JsonAccess(box a.resolve_refs(variables)?, box b.resolve_refs(variables)?)), } } pub fn var_refs(&self) -> Vec<&VarName> { - use AttrValueExpr::*; + use AttrValExpr::*; match self { Literal(s) => s.var_refs().collect(), VarRef(name) => vec![name], @@ -124,7 +124,7 @@ impl AttrValueExpr { refs.append(&mut c.var_refs()); refs } - JsonAccessIndex(box a, box b) => { + JsonAccess(box a, box b) => { let mut refs = a.var_refs(); refs.append(&mut b.var_refs()); refs @@ -132,60 +132,60 @@ impl AttrValueExpr { } } - pub fn eval(self, values: &HashMap) -> Result { + pub fn eval(self, values: &HashMap) -> Result { match self { - AttrValueExpr::Literal(x) => x.resolve_fully(&values), - AttrValueExpr::VarRef(ref name) => values + AttrValExpr::Literal(x) => x.resolve_fully(&values), + AttrValExpr::VarRef(ref name) => values .get(name) .cloned() .context(format!("Got unresolved variable {} while trying to evaluate expression {:?}", &name, &self)), - AttrValueExpr::BinOp(a, op, b) => { + AttrValExpr::BinOp(a, op, b) => { let a = a.eval(values)?; let b = b.eval(values)?; Ok(match op { - BinOp::Equals => PrimitiveValue::from(a == b), - BinOp::NotEquals => PrimitiveValue::from(a != b), - BinOp::And => PrimitiveValue::from(a.as_bool()? && b.as_bool()?), - BinOp::Or => PrimitiveValue::from(a.as_bool()? || b.as_bool()?), + BinOp::Equals => PrimVal::from(a == b), + BinOp::NotEquals => PrimVal::from(a != b), + BinOp::And => PrimVal::from(a.as_bool()? && b.as_bool()?), + BinOp::Or => PrimVal::from(a.as_bool()? || b.as_bool()?), - BinOp::Plus => PrimitiveValue::from(a.as_f64()? + b.as_f64()?), - BinOp::Minus => PrimitiveValue::from(a.as_f64()? - b.as_f64()?), - BinOp::Times => PrimitiveValue::from(a.as_f64()? * b.as_f64()?), - BinOp::Div => PrimitiveValue::from(a.as_f64()? / b.as_f64()?), - BinOp::Mod => PrimitiveValue::from(a.as_f64()? % b.as_f64()?), - BinOp::GT => PrimitiveValue::from(a.as_f64()? > b.as_f64()?), - BinOp::LT => PrimitiveValue::from(a.as_f64()? < b.as_f64()?), - BinOp::Elvis => PrimitiveValue::from(if a.0.is_empty() { b } else { a }), + BinOp::Plus => PrimVal::from(a.as_f64()? + b.as_f64()?), + BinOp::Minus => PrimVal::from(a.as_f64()? - b.as_f64()?), + BinOp::Times => PrimVal::from(a.as_f64()? * b.as_f64()?), + BinOp::Div => PrimVal::from(a.as_f64()? / b.as_f64()?), + BinOp::Mod => PrimVal::from(a.as_f64()? % b.as_f64()?), + BinOp::GT => PrimVal::from(a.as_f64()? > b.as_f64()?), + BinOp::LT => PrimVal::from(a.as_f64()? < b.as_f64()?), + BinOp::Elvis => PrimVal::from(if a.0.is_empty() { b } else { a }), }) } - AttrValueExpr::UnaryOp(op, a) => { + AttrValExpr::UnaryOp(op, a) => { let a = a.eval(values)?; Ok(match op { - UnaryOp::Not => PrimitiveValue::from(!a.as_bool()?), + UnaryOp::Not => PrimVal::from(!a.as_bool()?), }) } - AttrValueExpr::IfElse(cond, yes, no) => { + AttrValExpr::IfElse(cond, yes, no) => { if cond.eval(values)?.as_bool()? { yes.eval(values) } else { no.eval(values) } } - AttrValueExpr::JsonAccessIndex(val, index) => { + AttrValExpr::JsonAccess(val, index) => { let val = val.eval(values)?; let index = index.eval(values)?; match val.as_json_value()? { serde_json::Value::Array(val) => { let index = index.as_i32()?; let indexed_value = val.get(index as usize).unwrap_or(&serde_json::Value::Null); - Ok(PrimitiveValue::from(indexed_value)) + Ok(PrimVal::from(indexed_value)) } serde_json::Value::Object(val) => { let indexed_value = val .get(&index.as_string()?) - .or_else(|| val.get(&format!("{}", index.as_i32().ok()?))) + .or_else(|| val.get(&index.as_i32().ok()?.to_string())) .unwrap_or(&serde_json::Value::Null); - Ok(PrimitiveValue::from(indexed_value)) + Ok(PrimVal::from(indexed_value)) } _ => bail!("Unable to index into value {}", val), } diff --git a/src/value/attr_value/parser.rs b/src/value/attr_value/parser.rs index 4132e82..e345d80 100644 --- a/src/value/attr_value/parser.rs +++ b/src/value/attr_value/parser.rs @@ -53,34 +53,34 @@ fn parse_unary_op(i: &str) -> IResult<&str, UnaryOp, VerboseError<&str>> { // actual tree // ///////////////// -fn parse_factor(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_factor(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, unary_op) = opt(parse_unary_op)(i)?; let (i, factor) = alt(( context("expression", ws(delimited(tag("("), parse_expr, tag(")")))), context("if-expression", ws(parse_ifelse)), - context("literal", map(ws(parse_literal), |x| AttrValueExpr::Literal(AttrValue::parse_string(x)))), - context("identifier", map(ws(parse_identifier), |x| AttrValueExpr::VarRef(VarName(x.to_string())))), + context("literal", map(ws(parse_literal), |x| AttrValExpr::Literal(AttrVal::parse_string(x)))), + context("identifier", map(ws(parse_identifier), |x| AttrValExpr::VarRef(VarName(x.to_string())))), ))(i)?; Ok(( i, match unary_op { - Some(op) => AttrValueExpr::UnaryOp(op, box factor), + Some(op) => AttrValExpr::UnaryOp(op, box factor), None => factor, }, )) } -fn parse_object_index(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_object_index(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, initial) = parse_factor(i)?; let (i, remainder) = many0(alt(( delimited(tag("["), ws(parse_expr), tag("]")), - map(preceded(tag("."), parse_identifier), |x| AttrValueExpr::Literal(AttrValue::from_primitive(x))), + map(preceded(tag("."), parse_identifier), |x| AttrValExpr::Literal(AttrVal::from_primitive(x))), )))(i)?; - let indexes = remainder.into_iter().fold(initial, |acc, index| AttrValueExpr::JsonAccessIndex(box acc, box index)); + let indexes = remainder.into_iter().fold(initial, |acc, index| AttrValExpr::JsonAccess(box acc, box index)); Ok((i, indexes)) } -fn parse_term3(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_term3(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, initial) = parse_object_index(i)?; let (i, remainder) = many0(alt(( map(preceded(tag("*"), parse_object_index), |x| (BinOp::Times, x)), @@ -88,23 +88,23 @@ fn parse_term3(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { map(preceded(tag("%"), parse_object_index), |x| (BinOp::Mod, x)), )))(i)?; - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValueExpr::BinOp(box acc, op, box expr)); + let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); Ok((i, exprs)) } -fn parse_term2(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_term2(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, initial) = parse_term3(i)?; let (i, remainder) = many0(alt(( map(preceded(tag("+"), parse_term3), |x| (BinOp::Plus, x)), map(preceded(tag("-"), parse_term3), |x| (BinOp::Minus, x)), )))(i)?; - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValueExpr::BinOp(box acc, op, box expr)); + let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); Ok((i, exprs)) } -fn parse_term1(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_term1(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, initial) = parse_term2(i)?; let (i, remainder) = many0(alt(( map(preceded(tag("=="), parse_term2), |x| (BinOp::Equals, x)), @@ -113,11 +113,11 @@ fn parse_term1(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { map(preceded(tag("<"), parse_term2), |x| (BinOp::LT, x)), )))(i)?; - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValueExpr::BinOp(box acc, op, box expr)); + let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); Ok((i, exprs)) } -pub fn parse_expr(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +pub fn parse_expr(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, initial) = parse_term1(i)?; let (i, remainder) = many0(alt(( map(preceded(tag("&&"), parse_term1), |x| (BinOp::And, x)), @@ -125,22 +125,22 @@ pub fn parse_expr(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { map(preceded(tag("?:"), parse_term1), |x| (BinOp::Elvis, x)), )))(i)?; - let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValueExpr::BinOp(box acc, op, box expr)); + let exprs = remainder.into_iter().fold(initial, |acc, (op, expr)| AttrValExpr::BinOp(box acc, op, box expr)); Ok((i, exprs)) } -fn parse_ifelse(i: &str) -> IResult<&str, AttrValueExpr, VerboseError<&str>> { +fn parse_ifelse(i: &str) -> IResult<&str, AttrValExpr, VerboseError<&str>> { let (i, _) = tag("if")(i)?; let (i, a) = context("condition", ws(parse_expr))(i)?; let (i, _) = tag("then")(i)?; let (i, b) = context("true-case", ws(parse_expr))(i)?; let (i, _) = tag("else")(i)?; let (i, c) = context("false-case", ws(parse_expr))(i)?; - Ok((i, AttrValueExpr::IfElse(box a, box b, box c))) + Ok((i, AttrValExpr::IfElse(box a, box b, box c))) } -pub fn parse<'a>(i: &'a str) -> IResult<&'a str, AttrValueExpr, VerboseError<&'a str>> { +pub fn parse<'a>(i: &'a str) -> IResult<&'a str, AttrValExpr, VerboseError<&'a str>> { complete(parse_expr)(i) } @@ -150,64 +150,64 @@ mod test { use pretty_assertions::assert_eq; #[test] fn test_parser() { - assert_eq!(AttrValueExpr::Literal(AttrValue::from_primitive("12")), AttrValueExpr::parse("12").unwrap()); + assert_eq!(AttrValExpr::Literal(AttrVal::from_primitive("12")), AttrValExpr::parse("12").unwrap()); assert_eq!( - AttrValueExpr::UnaryOp(UnaryOp::Not, box AttrValueExpr::Literal(AttrValue::from_primitive("false"))), - AttrValueExpr::parse("!false").unwrap() + AttrValExpr::UnaryOp(UnaryOp::Not, box AttrValExpr::Literal(AttrVal::from_primitive("false"))), + AttrValExpr::parse("!false").unwrap() ); assert_eq!( - AttrValueExpr::BinOp( - box AttrValueExpr::Literal(AttrValue::from_primitive("12")), + AttrValExpr::BinOp( + box AttrValExpr::Literal(AttrVal::from_primitive("12")), BinOp::Plus, - box AttrValueExpr::Literal(AttrValue::from_primitive("2")) + box AttrValExpr::Literal(AttrVal::from_primitive("2")) ), - AttrValueExpr::parse("12 + 2").unwrap() + AttrValExpr::parse("12 + 2").unwrap() ); assert_eq!( - AttrValueExpr::UnaryOp( + AttrValExpr::UnaryOp( UnaryOp::Not, - box AttrValueExpr::BinOp( - box AttrValueExpr::Literal(AttrValue::from_primitive("1")), + box AttrValExpr::BinOp( + box AttrValExpr::Literal(AttrVal::from_primitive("1")), BinOp::Equals, - box AttrValueExpr::Literal(AttrValue::from_primitive("2")) + box AttrValExpr::Literal(AttrVal::from_primitive("2")) ) ), - AttrValueExpr::parse("!(1 == 2)").unwrap() + AttrValExpr::parse("!(1 == 2)").unwrap() ); assert_eq!( - AttrValueExpr::IfElse( - box AttrValueExpr::VarRef(VarName("a".to_string())), - box AttrValueExpr::VarRef(VarName("b".to_string())), - box AttrValueExpr::VarRef(VarName("c".to_string())), + AttrValExpr::IfElse( + box AttrValExpr::VarRef(VarName("a".to_string())), + box AttrValExpr::VarRef(VarName("b".to_string())), + box AttrValExpr::VarRef(VarName("c".to_string())), ), - AttrValueExpr::parse("if a then b else c").unwrap() + AttrValExpr::parse("if a then b else c").unwrap() ); assert_eq!( - AttrValueExpr::JsonAccessIndex( - box AttrValueExpr::VarRef(VarName("array".to_string())), - box AttrValueExpr::BinOp( - box AttrValueExpr::Literal(AttrValue::from_primitive("1")), + AttrValExpr::JsonAccess( + box AttrValExpr::VarRef(VarName("array".to_string())), + box AttrValExpr::BinOp( + box AttrValExpr::Literal(AttrVal::from_primitive("1")), BinOp::Plus, - box AttrValueExpr::Literal(AttrValue::from_primitive("2")) + box AttrValExpr::Literal(AttrVal::from_primitive("2")) ) ), - AttrValueExpr::parse(r#"(array)[1+2]"#).unwrap() + AttrValExpr::parse(r#"(array)[1+2]"#).unwrap() ); assert_eq!( - AttrValueExpr::JsonAccessIndex( - box AttrValueExpr::JsonAccessIndex( - box AttrValueExpr::VarRef(VarName("object".to_string())), - box AttrValueExpr::Literal(AttrValue::from_primitive("field".to_string())), + AttrValExpr::JsonAccess( + box AttrValExpr::JsonAccess( + box AttrValExpr::VarRef(VarName("object".to_string())), + box AttrValExpr::Literal(AttrVal::from_primitive("field".to_string())), ), - box AttrValueExpr::Literal(AttrValue::from_primitive("field2".to_string())), + box AttrValExpr::Literal(AttrVal::from_primitive("field2".to_string())), ), - AttrValueExpr::parse(r#"object.field.field2"#).unwrap() + AttrValExpr::parse(r#"object.field.field2"#).unwrap() ); } #[test] fn test_complex() { let parsed = - AttrValueExpr::parse(r#"if hi > 12 + 2 * 2 && 12 == 15 then "foo" else if !true then 'hi' else "{{bruh}}""#).unwrap(); + AttrValExpr::parse(r#"if hi > 12 + 2 * 2 && 12 == 15 then "foo" else if !true then 'hi' else "{{bruh}}""#).unwrap(); assert_eq!( r#"(if ((hi > ("12" + ("2" * "2"))) && ("12" == "15")) then "foo" else (if !"true" then "hi" else "{{bruh}}"))"#, diff --git a/src/value/primitive.rs b/src/value/primitive.rs index d818681..2ef4cb2 100644 --- a/src/value/primitive.rs +++ b/src/value/primitive.rs @@ -6,21 +6,21 @@ use std::{convert::TryFrom, fmt, iter::FromIterator}; use crate::impl_try_from; #[derive(Clone, Deserialize, Serialize, derive_more::From, Default)] -pub struct PrimitiveValue(pub String); +pub struct PrimVal(pub String); -impl fmt::Display for PrimitiveValue { +impl fmt::Display for PrimVal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) } } -impl fmt::Debug for PrimitiveValue { +impl fmt::Debug for PrimVal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "\"{}\"", self.0) } } /// Manually implement equality, to allow for values in different formats (i.e. "1" and "1.0") to still be considered as equal. -impl std::cmp::PartialEq for PrimitiveValue { +impl std::cmp::PartialEq for PrimVal { fn eq(&self, other: &Self) -> bool { if let (Ok(a), Ok(b)) = (self.as_f64(), other.as_f64()) { a == b @@ -30,56 +30,56 @@ impl std::cmp::PartialEq for PrimitiveValue { } } -impl FromIterator for PrimitiveValue { - fn from_iter>(iter: T) -> Self { - PrimitiveValue(iter.into_iter().join("")) +impl FromIterator for PrimVal { + fn from_iter>(iter: T) -> Self { + PrimVal(iter.into_iter().join("")) } } -impl std::str::FromStr for PrimitiveValue { +impl std::str::FromStr for PrimVal { type Err = anyhow::Error; /// parses the value, trying to turn it into a number and a boolean first, /// before deciding that it is a string. fn from_str(s: &str) -> Result { - Ok(PrimitiveValue::from_string(s.to_string())) + Ok(PrimVal::from_string(s.to_string())) } } -impl_try_from!(PrimitiveValue { +impl_try_from!(PrimVal { for String => |x| x.as_string(); for f64 => |x| x.as_f64(); for bool => |x| x.as_bool(); for Vec => |x| x.as_vec(); }); -impl From for PrimitiveValue { +impl From for PrimVal { fn from(x: bool) -> Self { - PrimitiveValue(x.to_string()) + PrimVal(x.to_string()) } } -impl From for PrimitiveValue { +impl From for PrimVal { fn from(s: i32) -> Self { - PrimitiveValue(s.to_string()) + PrimVal(s.to_string()) } } -impl From for PrimitiveValue { +impl From for PrimVal { fn from(s: f64) -> Self { - PrimitiveValue(s.to_string()) + PrimVal(s.to_string()) } } -impl From<&str> for PrimitiveValue { +impl From<&str> for PrimVal { fn from(s: &str) -> Self { - PrimitiveValue(s.to_string()) + PrimVal(s.to_string()) } } -impl From<&serde_json::Value> for PrimitiveValue { +impl From<&serde_json::Value> for PrimVal { fn from(v: &serde_json::Value) -> Self { - PrimitiveValue( + PrimVal( v.as_str() .map(|x| x.to_string()) .or_else(|| serde_json::to_string(v).ok()) @@ -88,9 +88,9 @@ impl From<&serde_json::Value> for PrimitiveValue { } } -impl PrimitiveValue { +impl PrimVal { pub fn from_string(s: String) -> Self { - PrimitiveValue(s) + PrimVal(s) } pub fn into_inner(self) -> String { diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index dc4fc9a..dcf3803 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -154,7 +154,7 @@ macro_rules! resolve_block { }; (@get_value $args:ident, $name:expr, = $default:expr) => { - $args.widget.get_attr($name).cloned().unwrap_or(AttrValue::from_primitive($default)) + $args.widget.get_attr($name).cloned().unwrap_or(AttrVal::from_primitive($default)) }; (@get_value $args:ident, $name:expr,) => { diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs index 5e90d2a..b6fc36d 100644 --- a/src/widgets/widget_definitions.rs +++ b/src/widgets/widget_definitions.rs @@ -1,5 +1,5 @@ use super::{run_command, BuilderArgs}; -use crate::{config, eww_state, resolve_block, value::AttrValue, widgets::widget_node}; +use crate::{config, eww_state, resolve_block, value::AttrVal, widgets::widget_node}; use anyhow::*; use gtk::{prelude::*, ImageExt}; use std::{cell::RefCell, collections::HashMap, rc::Rc}; @@ -377,7 +377,7 @@ fn build_gtk_image(bargs: &mut BuilderArgs) -> Result { // @prop width - width of the image // @prop height - height of the image prop(path: as_string, width: as_i32 = 10000, height: as_i32 = 10000) { - if path.ends_with(".gif") { + if path.ends_with(".gif") { let pixbuf_animation = gdk_pixbuf::PixbufAnimation::from_file(std::path::PathBuf::from(path))?; gtk_widget.set_from_animation(&pixbuf_animation); } else { diff --git a/src/widgets/widget_node.rs b/src/widgets/widget_node.rs index e9bf5dd..4b66924 100644 --- a/src/widgets/widget_node.rs +++ b/src/widgets/widget_node.rs @@ -5,7 +5,7 @@ use crate::{ WindowName, }, eww_state::EwwState, - value::{AttrName, AttrValue, VarName}, + value::{AttrName, AttrVal, VarName}, }; use anyhow::*; use dyn_clone; @@ -62,11 +62,11 @@ pub struct Generic { pub name: String, pub text_pos: Option, pub children: Vec>, - pub attrs: HashMap, + pub attrs: HashMap, } impl Generic { - pub fn get_attr(&self, key: &str) -> Result<&AttrValue> { + pub fn get_attr(&self, key: &str) -> Result<&AttrVal> { self.attrs.get(key).context(format!("attribute '{}' missing from use of '{}'", key, &self.name)) } @@ -98,7 +98,7 @@ impl WidgetNode for Generic { pub fn generate_generic_widget_node( defs: &HashMap, - local_env: &HashMap, + local_env: &HashMap, w: WidgetUse, ) -> Result> { if let Some(def) = defs.get(&w.name) {