Refactor and shorten debug output
This commit is contained in:
parent
b06162dcf5
commit
00580318e3
5 changed files with 69 additions and 48 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue