Refactor and shorten debug output

This commit is contained in:
elkowar 2020-10-18 22:54:21 +02:00
parent b06162dcf5
commit 00580318e3
5 changed files with 69 additions and 48 deletions

View file

@ -178,9 +178,7 @@ impl EwwConfig {
} }
#[repr(transparent)] #[repr(transparent)]
#[derive( #[derive(Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize)]
Debug, Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize,
)]
pub struct WindowName(String); pub struct WindowName(String);
impl std::borrow::Borrow<str> for WindowName { impl std::borrow::Borrow<str> for WindowName {
@ -195,6 +193,12 @@ impl fmt::Display for WindowName {
} }
} }
impl fmt::Debug for WindowName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "WindowName(\"{}\")", self.0)
}
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct EwwWindowDefinition { pub struct EwwWindowDefinition {
pub position: Coords, pub position: Coords,

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
config::WindowName, config::WindowName,
util, util,
value::{AttrName, StringOrVarRef, VarName}, value::{AttrName, AttrValueElement, VarName},
}; };
use anyhow::*; use anyhow::*;
use std::{collections::HashMap, process::Command, sync::Arc}; use std::{collections::HashMap, process::Command, sync::Arc};
@ -51,7 +51,7 @@ pub struct EwwWindowState {
} }
impl EwwWindowState { impl EwwWindowState {
/// register a new [StateChangeHandler] /// register a new [`StateChangeHandler`]
fn put_handler(&mut self, handler: StateChangeHandler) { fn put_handler(&mut self, handler: StateChangeHandler) {
let handler = Arc::new(handler); let handler = Arc::new(handler);
for var_name in handler.used_variables() { for var_name in handler.used_variables() {
@ -128,8 +128,8 @@ impl EwwState {
value value
.iter() .iter()
.map(|element| match element { .map(|element| match element {
StringOrVarRef::Primitive(primitive) => Ok(primitive.clone()), AttrValueElement::Primitive(primitive) => Ok(primitive.clone()),
StringOrVarRef::VarRef(var_name) => self AttrValueElement::VarRef(var_name) => self
.variables_state .variables_state
.get(var_name) .get(var_name)
.cloned() .cloned()
@ -148,28 +148,29 @@ impl EwwState {
&mut self, &mut self,
window_name: &WindowName, window_name: &WindowName,
local_env: &HashMap<VarName, AttrValue>, local_env: &HashMap<VarName, AttrValue>,
mut attributes: HashMap<AttrName, AttrValue>, attributes: HashMap<AttrName, AttrValue>,
set_value: F, set_value: F,
) { ) {
let handler = StateChangeHandler {
func: Box::new(set_value),
unresolved_values: attributes
.into_iter()
.map(|(attr_name, attr_value)| (attr_name, attr_value.resolve_one_level(local_env)))
.collect(),
};
handler.run_with_state(&self.variables_state);
// only store the handler if at least one variable is being used
if handler.used_variables().next().is_some() {
let window_state = self let window_state = self
.windows .windows
.entry(window_name.clone()) .entry(window_name.clone())
.or_insert_with(EwwWindowState::default); .or_insert_with(EwwWindowState::default);
let resolved_attributes: Vec<(AttrName, AttrValue)> = attributes
.drain()
.map(|(attr_name, attr_value)| (attr_name, attr_value.resolve_one_level(local_env)))
.collect();
let handler = StateChangeHandler {
func: Box::new(set_value),
unresolved_values: resolved_attributes,
};
handler.run_with_state(&self.variables_state);
window_state.put_handler(handler); window_state.put_handler(handler);
} }
} }
}
/// Run a command and get the output /// Run a command and get the output
pub fn run_command(cmd: &str) -> Result<PrimitiveValue> { pub fn run_command(cmd: &str) -> Result<PrimitiveValue> {

View file

@ -3,32 +3,39 @@ use std::{collections::HashMap, iter::FromIterator};
use super::*; use super::*;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, derive_more::Into, derive_more::From)] /// A value assigned to an attribute in a widget.
pub struct AttrValue(Vec<StringOrVarRef>); /// 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)]
pub struct AttrValue(Vec<AttrValueElement>);
impl fmt::Debug for AttrValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AttrValue({:?})", self.0)
}
}
impl IntoIterator for AttrValue { impl IntoIterator for AttrValue {
type IntoIter = std::vec::IntoIter<Self::Item>; type IntoIter = std::vec::IntoIter<Self::Item>;
type Item = StringOrVarRef; type Item = AttrValueElement;
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
self.0.into_iter() self.0.into_iter()
} }
} }
impl FromIterator<StringOrVarRef> for AttrValue { impl FromIterator<AttrValueElement> for AttrValue {
fn from_iter<T: IntoIterator<Item = StringOrVarRef>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = AttrValueElement>>(iter: T) -> Self {
let mut result = AttrValue(Vec::new()); AttrValue(iter.into_iter().collect())
result.0.extend(iter);
result
} }
} }
impl AttrValue { impl AttrValue {
pub fn from_primitive<T: Into<PrimitiveValue>>(v: T) -> Self { pub fn from_primitive<T: Into<PrimitiveValue>>(v: T) -> Self {
AttrValue(vec![StringOrVarRef::Primitive(v.into())]) AttrValue(vec![AttrValueElement::Primitive(v.into())])
} }
pub fn iter(&self) -> std::slice::Iter<StringOrVarRef> { pub fn iter(&self) -> std::slice::Iter<AttrValueElement> {
self.0.iter() self.0.iter()
} }
@ -39,9 +46,9 @@ impl AttrValue {
pub fn resolve_one_level(self, variables: &HashMap<VarName, AttrValue>) -> AttrValue { pub fn resolve_one_level(self, variables: &HashMap<VarName, AttrValue>) -> AttrValue {
self.into_iter() self.into_iter()
.flat_map(|entry| match entry { .flat_map(|entry| match entry {
StringOrVarRef::VarRef(var_name) => match variables.get(&var_name) { AttrValueElement::VarRef(var_name) => match variables.get(&var_name) {
Some(value) => value.0.clone(), Some(value) => value.0.clone(),
_ => vec![StringOrVarRef::VarRef(var_name)], _ => vec![AttrValueElement::VarRef(var_name)],
}, },
_ => vec![entry], _ => vec![entry],
}) })
@ -51,8 +58,8 @@ impl AttrValue {
pub fn resolve_fully(self, variables: &HashMap<VarName, PrimitiveValue>) -> Result<PrimitiveValue> { pub fn resolve_fully(self, variables: &HashMap<VarName, PrimitiveValue>) -> Result<PrimitiveValue> {
self.into_iter() self.into_iter()
.map(|element| match element { .map(|element| match element {
StringOrVarRef::Primitive(x) => Ok(x), AttrValueElement::Primitive(x) => Ok(x),
StringOrVarRef::VarRef(var_name) => variables AttrValueElement::VarRef(var_name) => variables
.get(&var_name) .get(&var_name)
.cloned() .cloned()
.with_context(|| format!("Unknown variable '{}' referenced", var_name)), .with_context(|| format!("Unknown variable '{}' referenced", var_name)),
@ -72,7 +79,7 @@ impl AttrValue {
if c == '}' { if c == '}' {
curly_count -= 1; curly_count -= 1;
if curly_count == 0 { if curly_count == 0 {
elements.push(StringOrVarRef::VarRef(VarName(std::mem::take(varref)))); elements.push(AttrValueElement::VarRef(VarName(std::mem::take(varref))));
cur_varref = None cur_varref = None
} }
} else { } else {
@ -84,7 +91,7 @@ impl AttrValue {
curly_count += 1; curly_count += 1;
if curly_count == 2 { if curly_count == 2 {
if !cur_word.is_empty() { if !cur_word.is_empty() {
elements.push(StringOrVarRef::primitive(std::mem::take(&mut cur_word))); elements.push(AttrValueElement::primitive(std::mem::take(&mut cur_word)));
} }
cur_varref = Some(String::new()) cur_varref = Some(String::new())
} }
@ -94,35 +101,44 @@ impl AttrValue {
} }
} }
if let Some(unfinished_varref) = cur_varref.take() { if let Some(unfinished_varref) = cur_varref.take() {
elements.push(StringOrVarRef::primitive(unfinished_varref)); elements.push(AttrValueElement::primitive(unfinished_varref));
} else if !cur_word.is_empty() { } else if !cur_word.is_empty() {
elements.push(StringOrVarRef::primitive(cur_word.to_owned())); elements.push(AttrValueElement::primitive(cur_word.to_owned()));
} }
AttrValue(elements) AttrValue(elements)
} }
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Serialize, Deserialize)]
pub enum StringOrVarRef { pub enum AttrValueElement {
Primitive(PrimitiveValue), Primitive(PrimitiveValue),
VarRef(VarName), VarRef(VarName),
} }
impl StringOrVarRef { impl fmt::Debug for AttrValueElement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AttrValueElement::Primitive(x) => write!(f, "Primitive({:?})", x),
AttrValueElement::VarRef(x) => write!(f, "VarRef({:?})", x),
}
}
}
impl AttrValueElement {
pub fn primitive(s: String) -> Self { pub fn primitive(s: String) -> Self {
StringOrVarRef::Primitive(PrimitiveValue::from_string(s)) AttrValueElement::Primitive(PrimitiveValue::from_string(s))
} }
pub fn as_var_ref(&self) -> Option<&VarName> { pub fn as_var_ref(&self) -> Option<&VarName> {
match self { match self {
StringOrVarRef::VarRef(x) => Some(&x), AttrValueElement::VarRef(x) => Some(&x),
_ => None, _ => None,
} }
} }
pub fn as_primitive(&self) -> Option<&PrimitiveValue> { pub fn as_primitive(&self) -> Option<&PrimitiveValue> {
match self { match self {
StringOrVarRef::Primitive(x) => Some(&x), AttrValueElement::Primitive(x) => Some(&x),
_ => None, _ => None,
} }
} }

View file

@ -5,11 +5,10 @@ use std::fmt;
pub mod attr_value; pub mod attr_value;
pub mod primitive; pub mod primitive;
pub mod string_with_varrefs;
pub use attr_value::*; pub use attr_value::*;
pub use primitive::*; pub use primitive::*;
pub use string_with_varrefs::*;
/// The name of a variable
#[repr(transparent)] #[repr(transparent)]
#[derive( #[derive(
Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize, RefCast, Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize, RefCast,
@ -34,6 +33,7 @@ impl fmt::Debug for VarName {
} }
} }
/// The name of an attribute
#[repr(transparent)] #[repr(transparent)]
#[derive( #[derive(
Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize, RefCast, Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize, RefCast,
@ -54,6 +54,6 @@ impl fmt::Display for AttrName {
impl fmt::Debug for AttrName { impl fmt::Debug for AttrName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "AttrName({})", self.0) write!(f, "AttrName(\"{}\")", self.0)
} }
} }

View file

@ -16,7 +16,7 @@ impl fmt::Display for PrimitiveValue {
} }
impl fmt::Debug for PrimitiveValue { impl fmt::Debug for PrimitiveValue {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"{}\"", self) write!(f, "\"{}\"", self.0)
} }
} }