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)]
#[derive(
Debug, Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize,
)]
#[derive(Clone, Hash, PartialEq, Eq, derive_more::AsRef, derive_more::From, derive_more::FromStr, Serialize, Deserialize)]
pub struct WindowName(String);
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)]
pub struct EwwWindowDefinition {
pub position: Coords,

View File

@ -1,7 +1,7 @@
use crate::{
config::WindowName,
util,
value::{AttrName, StringOrVarRef, VarName},
value::{AttrName, AttrValueElement, VarName},
};
use anyhow::*;
use std::{collections::HashMap, process::Command, sync::Arc};
@ -51,7 +51,7 @@ pub struct EwwWindowState {
}
impl EwwWindowState {
/// register a new [StateChangeHandler]
/// register a new [`StateChangeHandler`]
fn put_handler(&mut self, handler: StateChangeHandler) {
let handler = Arc::new(handler);
for var_name in handler.used_variables() {
@ -128,8 +128,8 @@ impl EwwState {
value
.iter()
.map(|element| match element {
StringOrVarRef::Primitive(primitive) => Ok(primitive.clone()),
StringOrVarRef::VarRef(var_name) => self
AttrValueElement::Primitive(primitive) => Ok(primitive.clone()),
AttrValueElement::VarRef(var_name) => self
.variables_state
.get(var_name)
.cloned()
@ -148,26 +148,27 @@ impl EwwState {
&mut self,
window_name: &WindowName,
local_env: &HashMap<VarName, AttrValue>,
mut attributes: HashMap<AttrName, AttrValue>,
attributes: HashMap<AttrName, AttrValue>,
set_value: F,
) {
let window_state = self
.windows
.entry(window_name.clone())
.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,
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);
window_state.put_handler(handler);
// only store the handler if at least one variable is being used
if handler.used_variables().next().is_some() {
let window_state = self
.windows
.entry(window_name.clone())
.or_insert_with(EwwWindowState::default);
window_state.put_handler(handler);
}
}
}

View File

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

View File

@ -5,11 +5,10 @@ use std::fmt;
pub mod attr_value;
pub mod primitive;
pub mod string_with_varrefs;
pub use attr_value::*;
pub use primitive::*;
pub use string_with_varrefs::*;
/// The name of a variable
#[repr(transparent)]
#[derive(
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)]
#[derive(
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 {
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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\"{}\"", self)
write!(f, "\"{}\"", self.0)
}
}