diff --git a/crates/eww/src/server.rs b/crates/eww/src/server.rs index c4c02d1..be4447d 100644 --- a/crates/eww/src/server.rs +++ b/crates/eww/src/server.rs @@ -46,7 +46,7 @@ pub fn initialize_server(paths: EwwPaths, action: Option) -> Resu gtk::init()?; - log::info!("Initializing script var handler"); + log::debug!("Initializing script var handler"); let script_var_handler = script_var_handler::init(ui_send.clone()); let mut app = app::App { @@ -107,7 +107,7 @@ fn init_async_part(paths: EwwPaths, ui_send: UnboundedSender tokio::spawn(async move { // Wait for application exit event let _ = crate::application_lifecycle::recv_exit().await; - log::info!("Forward task received exit event"); + log::debug!("Forward task received exit event"); // Then forward that to the application let _ = ui_send.send(app::DaemonCommand::KillServer); }) diff --git a/crates/yuck/src/config/widget_definition.rs b/crates/yuck/src/config/widget_definition.rs index ffdcfff..84ccb6e 100644 --- a/crates/yuck/src/config/widget_definition.rs +++ b/crates/yuck/src/config/widget_definition.rs @@ -29,7 +29,7 @@ impl FromAstElementContent for WidgetDefinition { let (name_span, name) = iter.expect_symbol().note(EXPECTED_WIDGET_DEF_FORMAT)?; let (args_span, expected_args) = iter .expect_array() - .wrong_expr_type_to(|_| FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end())) + .wrong_expr_type_to(|_, _| Some(FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end()))) .note(EXPECTED_WIDGET_DEF_FORMAT)?; let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::>()?; let widget = iter.expect_any().note(EXPECTED_WIDGET_DEF_FORMAT).and_then(WidgetUse::from_ast)?; diff --git a/crates/yuck/src/config/widget_use.rs b/crates/yuck/src/config/widget_use.rs index 96f7769..775d53f 100644 --- a/crates/yuck/src/config/widget_use.rs +++ b/crates/yuck/src/config/widget_use.rs @@ -4,7 +4,7 @@ use simplexpr::SimplExpr; use crate::{ config::attributes::AttrEntry, - error::AstResult, + error::{AstError, AstResult}, parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst}, }; use eww_shared_util::{AttrName, Span, VarName}; @@ -34,21 +34,7 @@ impl FromAst for WidgetUse { fn from_ast(e: Ast) -> AstResult { let span = e.span(); if let Ok(value) = e.clone().as_simplexpr() { - Ok(Self { - name: "label".to_string(), - name_span: span.point_span(), - attrs: Attributes::new( - span, - maplit::hashmap! { - AttrName("text".to_string()) => AttrEntry::new( - span, - Ast::SimplExpr(span.into(), value.clone()) - ) - }, - ), - children: Vec::new(), - span, - }) + Ok(label_from_simplexpr(value, span)) } else { let mut iter = e.try_ast_iter()?; let (name_span, name) = iter.expect_symbol()?; @@ -58,3 +44,21 @@ impl FromAst for WidgetUse { } } } + +fn label_from_simplexpr(value: SimplExpr, span: Span) -> WidgetUse { + WidgetUse { + name: "label".to_string(), + name_span: span.point_span(), + attrs: Attributes::new( + span, + maplit::hashmap! { + AttrName("text".to_string()) => AttrEntry::new( + span, + Ast::SimplExpr(span.into(), value.clone()) + ) + }, + ), + children: Vec::new(), + span, + } +} diff --git a/crates/yuck/src/error.rs b/crates/yuck/src/error.rs index ca90a50..c5f1980 100644 --- a/crates/yuck/src/error.rs +++ b/crates/yuck/src/error.rs @@ -34,6 +34,9 @@ pub enum AstError { #[error("Expected element {1}, but read {2}")] MismatchedElementName(Span, String, String), + #[error("Keyword `{1}` is missing a value")] + DanglingKeyword(Span, String), + #[error("Included file not found {}", .0.path)] IncludedFileNotFound(Include), @@ -81,9 +84,11 @@ impl AstError { AstError::ParseError { file_id, source: err } } - pub fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstError { + pub fn wrong_expr_type_to>(self, f: impl FnOnce(Span, AstType) -> Option) -> AstError { match self { - AstError::WrongExprType(span, ..) => AstError::FormFormatError(f(span.point_span())), + AstError::WrongExprType(span, expected, got) => { + f(span.point_span(), got).map(|x| x.into()).unwrap_or_else(|| AstError::WrongExprType(span, expected, got)) + } AstError::ErrorNote(s, err) => AstError::ErrorNote(s, Box::new(err.wrong_expr_type_to(f))), other => other, } @@ -98,6 +103,7 @@ impl Spanned for AstError { AstError::WrongExprType(span, ..) => *span, AstError::NotAValue(span, ..) => *span, AstError::MismatchedElementName(span, ..) => *span, + AstError::DanglingKeyword(span, _) => *span, AstError::AttrError(err) => err.span(), AstError::Other(span, ..) => *span, AstError::ConversionError(err) => err.value.span(), @@ -138,8 +144,9 @@ pub trait AstResultExt { fn context_label(self, label_span: Span, context: &str) -> AstResult; fn note(self, note: &str) -> AstResult; - /// Map any [AstError::WrongExprType]s error to a [FormFormatError] - fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult; + /// Map any [AstError::WrongExprType]s error to any other Into (such as a [FormFormatError]) + /// If the provided closure returns `None`, the error will be kept unmodified + fn wrong_expr_type_to>(self, f: impl FnOnce(Span, AstType) -> Option) -> AstResult; } impl AstResultExt for AstResult { @@ -151,7 +158,7 @@ impl AstResultExt for AstResult { self.map_err(|e| e.note(note)) } - fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult { + fn wrong_expr_type_to>(self, f: impl FnOnce(Span, AstType) -> Option) -> AstResult { self.map_err(|err| err.wrong_expr_type_to(f)) } } diff --git a/crates/yuck/src/format_diagnostic.rs b/crates/yuck/src/format_diagnostic.rs index ebac4f7..52d5e56 100644 --- a/crates/yuck/src/format_diagnostic.rs +++ b/crates/yuck/src/format_diagnostic.rs @@ -89,7 +89,7 @@ impl ToDiagnostic for AstError { AstError::WrongExprType(span, expected, actual) => gen_diagnostic! { msg = "Wrong type of expression", label = span => format!("Expected a `{}` here", expected), - note = format!("Expected: {}\nGot: {}", expected, actual), + note = format!("Expected: {}\n Got: {}", expected, actual), }, AstError::NotAValue(span, actual) => gen_diagnostic! { msg = format!("Expected value, but got `{}`", actual), @@ -101,7 +101,7 @@ impl ToDiagnostic for AstError { AstError::MismatchedElementName(span, expected, got) => gen_diagnostic! { msg = format!("Expected element `{}`, but found `{}`", expected, got), label = span => format!("Expected `{}` here", expected), - note = format!("Expected: {}\nGot: {}", expected, got), + note = format!("Expected: {}\n Got: {}", expected, got), }, AstError::ErrorContext { label_span, context, main_err } => { main_err.to_diagnostic().with_label(span_to_secondary_label(*label_span).with_message(context)) @@ -120,6 +120,10 @@ impl ToDiagnostic for AstError { label = extra_nodes_span => "these elements must not be here", note = "Consider wrapping the elements in some container element", }, + AstError::DanglingKeyword(span, keyword) => gen_diagnostic! { + msg = self, + label = span => "No value provided for this", + }, AstError::ErrorNote(note, source) => source.to_diagnostic().with_notes(vec![note.to_string()]), AstError::ValidationError(source) => source.to_diagnostic(), AstError::NoMoreElementsExpected(span) => gen_diagnostic!(self, span), diff --git a/crates/yuck/src/parser/ast.rs b/crates/yuck/src/parser/ast.rs index 2361ea5..ac48f38 100644 --- a/crates/yuck/src/parser/ast.rs +++ b/crates/yuck/src/parser/ast.rs @@ -27,7 +27,10 @@ pub enum AstType { impl Display for AstType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) + match self { + AstType::IntoPrimitive => write!(f, "primitive"), + _ => write!(f, "{:?}", self), + } } } diff --git a/crates/yuck/src/parser/ast_iterator.rs b/crates/yuck/src/parser/ast_iterator.rs index f1e9414..cee69dc 100644 --- a/crates/yuck/src/parser/ast_iterator.rs +++ b/crates/yuck/src/parser/ast_iterator.rs @@ -77,7 +77,7 @@ impl> AstIterator { } pub fn expect_key_values(&mut self) -> AstResult { - parse_key_values(self) + parse_key_values(self, true) } pub fn put_back(&mut self, ast: Ast) { @@ -98,7 +98,7 @@ impl> Iterator for AstIterator { } /// Parse consecutive `:keyword value` pairs from an expression iterator into an [Attributes]. -fn parse_key_values(iter: &mut AstIterator>) -> AstResult { +fn parse_key_values(iter: &mut AstIterator>, fail_on_dangling_kw: bool) -> AstResult { let mut data = HashMap::new(); let mut attrs_span = iter.remaining_span.point_span(); loop { @@ -110,9 +110,13 @@ fn parse_key_values(iter: &mut AstIterator>) -> AstRes data.insert(AttrName(kw), attr_value); } None => { - iter.iter.put_back(Ast::Keyword(key_span, kw)); - attrs_span.1 = iter.remaining_span.0; - return Ok(Attributes::new(attrs_span, data)); + if fail_on_dangling_kw { + return Err(AstError::DanglingKeyword(key_span, kw)); + } else { + iter.iter.put_back(Ast::Keyword(key_span, kw)); + attrs_span.1 = iter.remaining_span.0; + return Ok(Attributes::new(attrs_span, data)); + } } }, next => {