Improve error messages for unread elements in nodes and fix span handling in ast iterator
This commit is contained in:
parent
8fea52bda9
commit
6f1118bda4
12 changed files with 74 additions and 50 deletions
|
@ -98,6 +98,7 @@ mod backend {
|
|||
|
||||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let mut attrs = iter.expect_key_values()?;
|
||||
iter.expect_done().map_err(|e| e.note("Check if you are missing a colon in front of a key"))?;
|
||||
Ok(StrutDefinition { side: attrs.primitive_required("side")?, dist: attrs.primitive_required("distance")? })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ impl FromAstElementContent for Include {
|
|||
|
||||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let (path_span, path) = iter.expect_literal()?;
|
||||
iter.expect_done()?;
|
||||
Ok(Include { path: path.to_string(), path_span })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ impl FromAstElementContent for PollScriptVar {
|
|||
let mut attrs = iter.expect_key_values()?;
|
||||
let interval = attrs.primitive_required::<DynVal, _>("interval")?.as_duration()?;
|
||||
let (script_span, script) = iter.expect_literal()?;
|
||||
iter.expect_done()?;
|
||||
Ok(Self { name: VarName(name), command: VarSource::Shell(script_span, script.to_string()), interval })
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +81,7 @@ impl FromAstElementContent for ListenScriptVar {
|
|||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let (_, name) = iter.expect_symbol()?;
|
||||
let (command_span, script) = iter.expect_literal()?;
|
||||
iter.expect_done()?;
|
||||
Ok(Self { name: VarName(name), command: script.to_string(), command_span })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ impl FromAstElementContent for VarDefinition {
|
|||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let (_, name) = iter.expect_symbol()?;
|
||||
let (_, initial_value) = iter.expect_literal()?;
|
||||
iter.expect_done()?;
|
||||
Ok(Self { name: VarName(name), initial_value, span })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,7 @@ impl FromAstElementContent for WidgetDefinition {
|
|||
let (args_span, expected_args) = iter.expect_array()?;
|
||||
let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::<AstResult<_>>()?;
|
||||
let widget = iter.expect_any().and_then(WidgetUse::from_ast)?;
|
||||
// TODO verify that this was the last element in the list
|
||||
// iter.expect_done()?;
|
||||
iter.expect_done()?;
|
||||
Ok(Self { name, expected_args, widget, span, args_span })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ impl FromAstElementContent for WindowDefinition {
|
|||
let stacking = attrs.primitive_optional("stacking")?.unwrap_or(WindowStacking::Foreground);
|
||||
let geometry = attrs.ast_optional("geometry")?;
|
||||
let backend_options = BackendWindowOptions::from_attrs(&mut attrs)?;
|
||||
let widget = iter.expect_any()?;
|
||||
let widget = iter.expect_any().and_then(WidgetUse::from_ast)?;
|
||||
iter.expect_done()?;
|
||||
Ok(Self { name, monitor_number, resizable, widget, stacking, geometry, backend_options })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ impl FromAstElementContent for WindowGeometry {
|
|||
|
||||
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
|
||||
let mut attrs = iter.expect_key_values()?;
|
||||
iter.expect_done().map_err(|e| e.note("Check if you are missing a colon in front of a key"))?;
|
||||
Ok(WindowGeometry {
|
||||
anchor_point: attrs.primitive_optional("anchor")?.unwrap_or_default(),
|
||||
size: Coords {
|
||||
|
|
|
@ -21,6 +21,8 @@ pub enum AstError {
|
|||
MissingNode(Span),
|
||||
#[error("Too many elements, must be exactly {1}")]
|
||||
TooManyNodes(Span, i32),
|
||||
#[error("Did not expect any further elements here. Make sure your format is correct")]
|
||||
NoMoreElementsExpected(Span),
|
||||
|
||||
#[error("Wrong type of expression: Expected {1} but got {2}")]
|
||||
WrongExprType(Span, AstType, AstType),
|
||||
|
@ -91,6 +93,7 @@ impl Spanned for AstError {
|
|||
AstError::ValidationError(error) => error.span(),
|
||||
AstError::ParseError { file_id, source } => get_parse_error_span(*file_id, source),
|
||||
AstError::ErrorNote(_, err) => err.span(),
|
||||
AstError::NoMoreElementsExpected(span) => *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ impl ToDiagnostic for AstError {
|
|||
},
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,15 +24,11 @@ macro_rules! return_or_put_back {
|
|||
pub fn $name(&mut self) -> AstResult<$t> {
|
||||
let expr_type = $expr_type;
|
||||
match self.expect_any()? {
|
||||
$p => {
|
||||
let (span, value) = $ret;
|
||||
self.remaining_span.1 = span.1;
|
||||
Ok((span, value))
|
||||
}
|
||||
$p => Ok($ret),
|
||||
other => {
|
||||
let span = other.span();
|
||||
let actual_type = other.expr_type();
|
||||
self.iter.put_back(other);
|
||||
self.put_back(other);
|
||||
Err(AstError::WrongExprType(span, expr_type, actual_type))
|
||||
}
|
||||
}
|
||||
|
@ -53,20 +49,37 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
|
|||
AstIterator { remaining_span: span, iter: itertools::put_back(iter) }
|
||||
}
|
||||
|
||||
pub fn expect_any<T: FromAst>(&mut self) -> AstResult<T> {
|
||||
self.iter.next().or_missing(self.remaining_span.point_span()).and_then(T::from_ast)
|
||||
pub fn expect_any(&mut self) -> AstResult<Ast> {
|
||||
self.next().or_missing(self.remaining_span.point_span())
|
||||
}
|
||||
|
||||
pub fn expect_done(&mut self) -> AstResult<()> {
|
||||
if let Some(next) = self.next() {
|
||||
self.put_back(next);
|
||||
Err(AstError::NoMoreElementsExpected(self.remaining_span))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
|
||||
parse_key_values(self)
|
||||
}
|
||||
|
||||
pub fn put_back(&mut self, ast: Ast) {
|
||||
self.remaining_span.0 = ast.span().0;
|
||||
self.iter.put_back(ast)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Iterator<Item = Ast>> Iterator for AstIterator<I> {
|
||||
type Item = Ast;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next()
|
||||
self.iter.next().map(|x| {
|
||||
self.remaining_span.0 = x.span().1;
|
||||
x
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,9 @@ impl<T: FromAstElementContent> FromAst for T {
|
|||
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||
let span = e.span();
|
||||
let mut iter = e.try_ast_iter()?;
|
||||
let (_, element_name) = iter.expect_symbol()?;
|
||||
let (element_name_span, element_name) = iter.expect_symbol()?;
|
||||
if Self::get_element_name() != element_name {
|
||||
return Err(AstError::MismatchedElementName(span, Self::get_element_name().to_string(), element_name));
|
||||
return Err(AstError::MismatchedElementName(element_name_span, Self::get_element_name().to_string(), element_name));
|
||||
}
|
||||
Self::from_tail(span, iter)
|
||||
}
|
||||
|
|
|
@ -1,45 +1,44 @@
|
|||
(defwidget bar []
|
||||
(box :orientation "h" :hexpand true
|
||||
(workspaces)
|
||||
(music)
|
||||
(sidestuff)))
|
||||
|
||||
(box :orientation "h" :hexpand true
|
||||
(workspaces)
|
||||
(music)
|
||||
(sidestuff)))
|
||||
(defwidget sidestuff []
|
||||
(box :class "sidestuff" :orientation "h" :space-evenly false :halign "end"
|
||||
(slider-vol)
|
||||
(slider-ram)
|
||||
(time)))
|
||||
(box :class "sidestuff" :orientation "h" :space-evenly false :halign "end"
|
||||
(slider-vol)
|
||||
(slider-ram)
|
||||
(time)))
|
||||
|
||||
(defwidget workspaces []
|
||||
(box :class "workspaces" :orientation "h" :space-evenly true :halign "start"
|
||||
(button :onclick "wmctrl -s 0" 1)
|
||||
(button :onclick "wmctrl -s 1" 2)
|
||||
(button :onclick "wmctrl -s 2" 3)
|
||||
(button :onclick "wmctrl -s 3" 4)
|
||||
(button :onclick "wmctrl -s 4" 5)
|
||||
(button :onclick "wmctrl -s 5" 6)
|
||||
(button :onclick "wmctrl -s 6" 7)
|
||||
(button :onclick "wmctrl -s 7" 8)
|
||||
(button :onclick "wmctrl -s 8" 9)))
|
||||
(box :class "workspaces" :orientation "h" :space-evenly true :halign "start"
|
||||
(button :onclick "wmctrl -s 0" 1)
|
||||
(button :onclick "wmctrl -s 1" 2)
|
||||
(button :onclick "wmctrl -s 2" 3)
|
||||
(button :onclick "wmctrl -s 3" 4)
|
||||
(button :onclick "wmctrl -s 4" 5)
|
||||
(button :onclick "wmctrl -s 5" 6)
|
||||
(button :onclick "wmctrl -s 6" 7)
|
||||
(button :onclick "wmctrl -s 7" 8)
|
||||
(button :onclick "wmctrl -s 8" 9)))
|
||||
|
||||
(defwidget music []
|
||||
(box :class "music" :orientation "h" :space-evenly false :halign "center"
|
||||
{ ' ' + music}))
|
||||
(box :class "music" :orientation "h" :space-evenly false :halign "center"
|
||||
{ ' ' + music}))
|
||||
|
||||
(defwidget slider-vol []
|
||||
(box :class "slider-vol" :orientation "h" :space-evenly "false"
|
||||
(box :class "label-vol" ""
|
||||
(scale :min 0 :max 101 :value volume :onchange "amixer -D pulse sset Master {}%"))))
|
||||
(box :class "slider-vol" :orientation "h" :space-evenly "false"
|
||||
(box :class "label-vol" ""
|
||||
(scale :min 0 :max 101 :value volume :onchange "amixer -D pulse sset Master {}%"))))
|
||||
|
||||
(defwidget slider-ram []
|
||||
(box :orientation "h" :class "slider-ram" :space-evenly false
|
||||
(box :class "label-ram" ""
|
||||
(scale :min 0 :max 101 :active false :value EWW_RAM))))
|
||||
(box :orientation "h" :class "slider-ram" :space-evenly false
|
||||
(box :class "label-ram" ""
|
||||
(scale :min 0 :max 101 :active false :value EWW_RAM))))
|
||||
|
||||
|
||||
(defwidget time []
|
||||
(box :class "time"
|
||||
{hour + ":" + min + " " + month + " " + number_day + ", " + year_full}))
|
||||
(box :class "time"
|
||||
{hour + ":" + min + " " + month + " " + number_day + ", " + year_full}))
|
||||
|
||||
|
||||
(defpoll music :interval "5s" "playerctl metadata --format '{{ artist }} - {{ title }}' || true")
|
||||
|
@ -51,12 +50,14 @@
|
|||
(defpoll hour :interval "1m" "date '+%H'")
|
||||
(defpoll year_full :interval "15h" "date '+%Y'")
|
||||
|
||||
(deflisten battery-remaining "/sys/class/power_supply/BAT0/capacity")
|
||||
(deflisten battery-remaining "tail -f /sys/class/power_supply/BAT0/capacity")
|
||||
|
||||
(defwindow bar
|
||||
:screen 0
|
||||
:focusable true
|
||||
:windowtype "dock"
|
||||
:geometry (geometry :x "0%" :y "0%" :width "100%" :height "4%")
|
||||
:reserve (struts :side "top" :distance "4%")
|
||||
(bar))
|
||||
:screen 0
|
||||
:focusable true
|
||||
:windowtype "dock"
|
||||
:geometry (geometry :x "0%" :y "0%" :width "100%" :height "4%")
|
||||
:reserve (struts :side "top" :distance "4%")
|
||||
(bar))
|
||||
|
||||
; asdf
|
||||
|
|
Loading…
Add table
Reference in a new issue