From 27ce9e798a87ea8950628760a82dd41ccf17cf1b Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Sun, 1 Aug 2021 17:36:49 +0200 Subject: [PATCH] Fix error messages for script-var definitions --- crates/eww/src/widgets/widget_definitions.rs | 2 +- .../yuck/src/config/script_var_definition.rs | 22 ++++++++++++------- .../snapshots/yuck__config__test__config.snap | 5 +++-- crates/yuck/src/config/var_definition.rs | 18 +++++++-------- crates/yuck/src/error.rs | 9 ++++++-- crates/yuck/src/parser/ast_iterator.rs | 2 +- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index 4ea9b03..61e4744 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -8,7 +8,7 @@ use gtk::{self, prelude::*, ImageExt}; use std::{cell::RefCell, collections::HashMap, rc::Rc, time::Duration}; use yuck::{ config::validate::ValidationError, - error::{AstError, AstResult, ResultExt}, + error::{AstError, AstResult, AstResultExt}, parser::from_ast::FromAst, }; diff --git a/crates/yuck/src/config/script_var_definition.rs b/crates/yuck/src/config/script_var_definition.rs index a792fc7..82d0928 100644 --- a/crates/yuck/src/config/script_var_definition.rs +++ b/crates/yuck/src/config/script_var_definition.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use simplexpr::{dynval::DynVal, SimplExpr}; use crate::{ - error::{AstError, AstResult}, + error::{AstError, AstResult, AstResultExt}, parser::{ ast::Ast, ast_iterator::AstIterator, @@ -66,12 +66,15 @@ impl FromAstElementContent for PollScriptVar { } fn from_tail>(span: Span, mut iter: AstIterator) -> AstResult { - let (name_span, name) = iter.expect_symbol()?; - let mut attrs = iter.expect_key_values()?; - let interval = attrs.primitive_required::("interval")?.as_duration()?; - let (script_span, script) = iter.expect_literal()?; - iter.expect_done()?; - Ok(Self { name_span, name: VarName(name), command: VarSource::Shell(script_span, script.to_string()), interval }) + let result: AstResult<_> = try { + let (name_span, name) = iter.expect_symbol()?; + let mut attrs = iter.expect_key_values()?; + let interval = attrs.primitive_required::("interval")?.as_duration()?; + let (script_span, script) = iter.expect_literal()?; + iter.expect_done()?; + Self { name_span, name: VarName(name), command: VarSource::Shell(script_span, script.to_string()), interval } + }; + result.note(r#"Expected format: `(defpoll name :interval "10s" "echo 'a shell script'")`"#) } } @@ -88,9 +91,12 @@ impl FromAstElementContent for ListenScriptVar { } fn from_tail>(span: Span, mut iter: AstIterator) -> AstResult { + let result: AstResult<_> = try { let (name_span, name) = iter.expect_symbol()?; let (command_span, script) = iter.expect_literal()?; iter.expect_done()?; - Ok(Self { name_span, name: VarName(name), command: script.to_string(), command_span }) + Self { name_span, name: VarName(name), command: script.to_string(), command_span } + }; + result.note(r#"Expected format: `(deflisten name "tail -f /tmp/example")`"#) } } diff --git a/crates/yuck/src/config/snapshots/yuck__config__test__config.snap b/crates/yuck/src/config/snapshots/yuck__config__test__config.snap index d4a0ba3..0c4fe00 100644 --- a/crates/yuck/src/config/snapshots/yuck__config__test__config.snap +++ b/crates/yuck/src/config/snapshots/yuck__config__test__config.snap @@ -14,7 +14,7 @@ Config( widget: WidgetUse( name: "foo", attrs: Attributes( - span: Span(51, 61, 62), + span: Span(51, 61, 0), attrs: { AttrName("arg"): AttrEntry( key_span: Span(52, 56, 0), @@ -52,7 +52,7 @@ Config( widget: WidgetUse( name: "bar", attrs: Attributes( - span: Span(467, 478, 479), + span: Span(467, 478, 0), attrs: { AttrName("arg"): AttrEntry( key_span: Span(468, 472, 0), @@ -88,6 +88,7 @@ Config( name: VarName("stuff"), command: "tail -f stuff", command_span: Span(168, 183, 0), + name_span: Span(162, 167, 0), )), }, ) diff --git a/crates/yuck/src/config/var_definition.rs b/crates/yuck/src/config/var_definition.rs index cd39a8e..948d81a 100644 --- a/crates/yuck/src/config/var_definition.rs +++ b/crates/yuck/src/config/var_definition.rs @@ -2,14 +2,11 @@ use std::collections::HashMap; use simplexpr::{dynval::DynVal, SimplExpr}; -use crate::{ - error::AstResult, - parser::{ +use crate::{error::{AstResult, AstResultExt}, parser::{ ast::Ast, ast_iterator::AstIterator, from_ast::{FromAst, FromAstElementContent}, - }, -}; + }}; use eww_shared_util::{AttrName, Span, VarName}; #[derive(Debug, PartialEq, Eq, Clone, serde::Serialize)] @@ -25,9 +22,12 @@ impl FromAstElementContent for VarDefinition { } fn from_tail>(span: Span, mut iter: AstIterator) -> AstResult { - let (_, name) = iter.expect_symbol()?; - let (_, initial_value) = iter.expect_literal()?; - iter.expect_done()?; - Ok(Self { name: VarName(name), initial_value, span }) + let result: AstResult<_> = try { + let (_, name) = iter.expect_symbol()?; + let (_, initial_value) = iter.expect_literal()?; + iter.expect_done()?; + Self { name: VarName(name), initial_value, span } + }; + result.note(r#"Expected format: `(defvar name "initial-value")`"#) } } diff --git a/crates/yuck/src/error.rs b/crates/yuck/src/error.rs index 9c22e2a..c12756c 100644 --- a/crates/yuck/src/error.rs +++ b/crates/yuck/src/error.rs @@ -122,12 +122,17 @@ impl OptionAstErrorExt for Option { } } -pub trait ResultExt { +pub trait AstResultExt { fn context_label(self, label_span: Span, context: &str) -> AstResult; + fn note(self, note: &str) -> AstResult; } -impl ResultExt for AstResult { +impl AstResultExt for AstResult { fn context_label(self, label_span: Span, context: &str) -> AstResult { self.map_err(|e| AstError::ErrorContext { label_span, context: context.to_string(), main_err: Box::new(e) }) } + + fn note(self, note: &str) -> AstResult { + self.map_err(|e| e.note(note)) + } } diff --git a/crates/yuck/src/parser/ast_iterator.rs b/crates/yuck/src/parser/ast_iterator.rs index c2b5663..d2db491 100644 --- a/crates/yuck/src/parser/ast_iterator.rs +++ b/crates/yuck/src/parser/ast_iterator.rs @@ -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 { let mut data = HashMap::new(); - let mut attrs_span = Span(iter.remaining_span.0, iter.remaining_span.0, iter.remaining_span.1); + let mut attrs_span = iter.remaining_span.point_span(); loop { match iter.next() { Some(Ast::Keyword(key_span, kw)) => match iter.next() {