diff --git a/src/config.rs b/src/config.rs index 28c5a66..b3f687e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,8 @@ use std::{ str::FromStr, }; +// https://michael-f-bryan.github.io/static-analyser-in-rust/book/codemap.html + type VarName = String; type AttrValue = String; type AttrName = String; @@ -24,48 +26,6 @@ impl FromExpr for Expr { } } -#[derive(Debug, Eq, PartialEq)] -pub enum DefType { - Widget, -} - -impl FromStr for DefType { - type Err = (); - - fn from_str(s: &str) -> Result { - match s { - "defwidget" => Ok(DefType::Widget), - _ => Err(()), - } - } -} - -#[derive(Debug, Eq, PartialEq)] -pub struct Definitional { - def_type: DefType, - name: String, - attrs: HashMap, - children: Vec, - span: Span, -} - -impl FromExpr for Definitional { - fn from_expr(e: Expr) -> AstResult { - let span = e.span(); - spanned!(e.span(), { - let list = e.as_list()?; - let mut iter = ExprIterator::new(list.into_iter()); - let (span, def_type) = iter.next_symbol()?; - let def_type = def_type.parse().map_err(|_| AstError::InvalidDefinition(Some(span)))?; - - let (_, name) = iter.next_symbol()?; - let attrs = iter.key_values()?; - let children = iter.map(|x| C::from_expr(x)).collect::>>()?; - Definitional { span, def_type, name, attrs, children } - }) - } -} - #[derive(Debug, Eq, PartialEq)] pub struct Element { name: String, @@ -80,8 +40,8 @@ impl FromExpr for Element { spanned!(e.span(), { let list = e.as_list()?; let mut iter = ExprIterator::new(list.into_iter()); - let (_, name) = iter.next_symbol()?; - let attrs = iter.key_values()?; + let (_, name) = iter.expect_symbol()?; + let attrs = iter.expect_key_values()?; let children = iter.map(C::from_expr).collect::>>()?; Element { span, name, attrs, children } }) @@ -101,9 +61,6 @@ mod test { insta::assert_debug_snapshot!( Element::::from_expr(parser.parse("(box :bar 12 :baz \"hi\" foo (bar))").unwrap()).unwrap() ); - insta::assert_debug_snapshot!( - Definitional::::from_expr(parser.parse("(defwidget box (child) (child2))").unwrap()).unwrap() - ); }); } } diff --git a/src/expr.rs b/src/expr.rs index 099b5e2..97a0b92 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -15,7 +15,7 @@ impl std::fmt::Display for Span { impl std::fmt::Debug for Span { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self) + write!(f, "{}..{}", self.0, self.1) } } @@ -36,7 +36,7 @@ impl Display for ExprType { } } -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone)] pub enum Expr { List(Span, Vec), Table(Span, Vec<(Expr, Expr)>), @@ -48,22 +48,29 @@ pub enum Expr { } macro_rules! as_func { - ($exprtype:expr, $name:ident < $t:ty > = $p:pat => $value:expr) => { + ($exprtype:expr, $name:ident $nameref:ident < $t:ty > = $p:pat => $value:expr) => { pub fn $name(self) -> Result<$t, AstError> { match self { $p => Ok($value), x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())), } } + + pub fn $nameref(&self) -> Result<&$t, AstError> { + match self { + $p => Ok($value), + x => Err(AstError::WrongExprType(Some(x.span()), $exprtype, x.expr_type())), + } + } }; } impl Expr { - as_func!(ExprType::Str, as_str = Expr::Str(_, x) => x); + as_func!(ExprType::Str, as_str as_str_ref = Expr::Str(_, x) => x); - as_func!(ExprType::Symbol, as_symbol = Expr::Symbol(_, x) => x); + as_func!(ExprType::Symbol, as_symbol as_symbol_ref = Expr::Symbol(_, x) => x); - as_func!(ExprType::List, as_list> = Expr::List(_, x) => x); + as_func!(ExprType::List, as_list as_list_ref> = Expr::List(_, x) => x); pub fn expr_type(&self) -> ExprType { match self { @@ -88,6 +95,13 @@ impl Expr { Expr::Comment(span) => *span, } } + + pub fn first_list_elem(&self) -> Option<&Expr> { + match self { + Expr::List(_, list) => list.first(), + _ => None, + } + } } impl std::fmt::Display for Expr { @@ -104,6 +118,20 @@ impl std::fmt::Display for Expr { } } } +impl std::fmt::Debug for Expr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use Expr::*; + match self { + Number(span, x) => write!(f, "Number<{}>({})", span, x), + List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(), + Table(span, x) => f.debug_tuple(&format!("Table<{}>", span)).field(x).finish(), + Keyword(span, x) => write!(f, "Number<{}>({})", span, x), + Symbol(span, x) => write!(f, "Symbol<{}>({})", span, x), + Str(span, x) => write!(f, "Str<{}>({})", span, x), + Comment(span) => write!(f, "Comment<{}>", span), + } + } +} pub struct ExprIterator> { iter: itertools::PutBack, @@ -128,15 +156,19 @@ macro_rules! return_or_put_back { } impl> ExprIterator { - return_or_put_back!(next_symbol, ExprType::Symbol, (Span, String) = Expr::Symbol(span, x) => (span, x)); + return_or_put_back!(expect_symbol, ExprType::Symbol, (Span, String) = Expr::Symbol(span, x) => (span, x)); - return_or_put_back!(next_string, ExprType::Str, (Span, String) = Expr::Str(span, x) => (span, x)); + return_or_put_back!(expect_string, ExprType::Str, (Span, String) = Expr::Str(span, x) => (span, x)); + + return_or_put_back!(expect_number, ExprType::Number, (Span, i32) = Expr::Number(span, x) => (span, x)); + + return_or_put_back!(expect_list, ExprType::List, (Span, Vec) = Expr::List(span, x) => (span, x)); pub fn new(iter: I) -> Self { ExprIterator { iter: itertools::put_back(iter) } } - pub fn key_values(&mut self) -> AstResult> { + pub fn expect_key_values(&mut self) -> AstResult> { parse_key_values(&mut self.iter) } } diff --git a/src/lib.rs b/src/lib.rs index d4a6f66..5135ce4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,7 @@ fn test() { r#"{:key value 12 "hi" (test) (1 2 3)}"#, r#"; test"#, r#"(f arg ; test - arg2)"# + arg2)"#, + "\"h\\\"i\"" ); } diff --git a/src/snapshots/eww_config__config__test__test-2.snap b/src/snapshots/eww_config__config__test__test-2.snap index 39b709c..991e320 100644 --- a/src/snapshots/eww_config__config__test__test-2.snap +++ b/src/snapshots/eww_config__config__test__test-2.snap @@ -8,22 +8,14 @@ Definitional { name: "box", attrs: {}, children: [ - List( - 15..22, + List<15..22>( [ - Symbol( - 16..21, - "child", - ), + Symbol<16..21>(child), ], ), - List( - 23..31, + List<23..31>( [ - Symbol( - 24..30, - "child2", - ), + Symbol<24..30>(child2), ], ), ], diff --git a/src/snapshots/eww_config__config__test__test.snap b/src/snapshots/eww_config__config__test__test.snap index b58093b..2a5ccaa 100644 --- a/src/snapshots/eww_config__config__test__test.snap +++ b/src/snapshots/eww_config__config__test__test.snap @@ -6,27 +6,14 @@ expression: "Element::::from_expr(parser.parse(\"(box :ba Element { name: "box", attrs: { - ":bar": Number( - 10..12, - 12, - ), - ":baz": Str( - 18..22, - "hi", - ), + ":baz": Str<18..22>(hi), + ":bar": Number<10..12>(12), }, children: [ - Symbol( - 23..26, - "foo", - ), - List( - 27..32, + Symbol<23..26>(foo), + List<27..32>( [ - Symbol( - 28..31, - "bar", - ), + Symbol<28..31>(bar), ], ), ], diff --git a/src/snapshots/eww_config__test-10.snap b/src/snapshots/eww_config__test-10.snap index 2d0f6c5..50bf3b4 100644 --- a/src/snapshots/eww_config__test-10.snap +++ b/src/snapshots/eww_config__test-10.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(r#\"(test \"h\\\"i\")\"#)" --- Ok( - List( - 0..13, + List<0..13>( [ - Symbol( - 1..5, - "test", - ), - Str( - 6..12, - "h\\\"i", - ), + Symbol<1..5>(test), + Str<6..12>(h\"i), ], ), ) diff --git a/src/snapshots/eww_config__test-11.snap b/src/snapshots/eww_config__test-11.snap index ae042cc..8437f61 100644 --- a/src/snapshots/eww_config__test-11.snap +++ b/src/snapshots/eww_config__test-11.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(r#\"(test \" hi \")\"#)" --- Ok( - List( - 0..13, + List<0..13>( [ - Symbol( - 1..5, - "test", - ), - Str( - 6..12, - " hi ", - ), + Symbol<1..5>(test), + Str<6..12>( hi ), ], ), ) diff --git a/src/snapshots/eww_config__test-12.snap b/src/snapshots/eww_config__test-12.snap index 96fcd40..1f7e872 100644 --- a/src/snapshots/eww_config__test-12.snap +++ b/src/snapshots/eww_config__test-12.snap @@ -1,42 +1,21 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(+ (1 2 (* 2 5)))\")" --- Ok( - List( - 0..17, + List<0..17>( [ - Symbol( - 1..2, - "+", - ), - List( - 3..16, + Symbol<1..2>(+), + List<3..16>( [ - Number( - 4..5, - 1, - ), - Number( - 6..7, - 2, - ), - List( - 8..15, + Number<4..5>(1), + Number<6..7>(2), + List<8..15>( [ - Symbol( - 9..10, - "*", - ), - Number( - 11..12, - 2, - ), - Number( - 13..14, - 5, - ), + Symbol<9..10>(*), + Number<11..12>(2), + Number<13..14>(5), ], ), ], diff --git a/src/snapshots/eww_config__test-13.snap b/src/snapshots/eww_config__test-13.snap index aeed887..9b51e53 100644 --- a/src/snapshots/eww_config__test-13.snap +++ b/src/snapshots/eww_config__test-13.snap @@ -1,57 +1,30 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(r#\"{:key value 12 \"hi\" (test) (1 2 3)}\"#)" --- Ok( - Table( - 0..35, + Table<0..35>( [ ( - Keyword( - 1..5, - ":key", - ), - Symbol( - 6..11, - "value", - ), + Number<1..5>(:key), + Symbol<6..11>(value), ), ( - Number( - 12..14, - 12, - ), - Str( - 15..19, - "hi", - ), + Number<12..14>(12), + Str<15..19>(hi), ), ( - List( - 20..26, + List<20..26>( [ - Symbol( - 21..25, - "test", - ), + Symbol<21..25>(test), ], ), - List( - 27..34, + List<27..34>( [ - Number( - 28..29, - 1, - ), - Number( - 30..31, - 2, - ), - Number( - 32..33, - 3, - ), + Number<28..29>(1), + Number<30..31>(2), + Number<32..33>(3), ], ), ), diff --git a/src/snapshots/eww_config__test-14.snap b/src/snapshots/eww_config__test-14.snap index 5b8d869..3abe4ce 100644 --- a/src/snapshots/eww_config__test-14.snap +++ b/src/snapshots/eww_config__test-14.snap @@ -1,10 +1,8 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(r#\"; test\"#)" --- Ok( - Comment( - 0..6, - ), + Comment<0..6>, ) diff --git a/src/snapshots/eww_config__test-15.snap b/src/snapshots/eww_config__test-15.snap index b2943ca..c2f54ba 100644 --- a/src/snapshots/eww_config__test-15.snap +++ b/src/snapshots/eww_config__test-15.snap @@ -4,24 +4,12 @@ expression: "p.parse(r#\"(f arg ; test\n arg2)\"#)" --- Ok( - List( - 0..27, + List<0..27>( [ - Symbol( - 1..2, - "f", - ), - Symbol( - 3..6, - "arg", - ), - Comment( - 7..13, - ), - Symbol( - 22..26, - "arg2", - ), + Symbol<1..2>(f), + Symbol<3..6>(arg), + Comment<7..13>, + Symbol<22..26>(arg2), ], ), ) diff --git a/src/snapshots/eww_config__test-16.snap b/src/snapshots/eww_config__test-16.snap new file mode 100644 index 0000000..021fcd1 --- /dev/null +++ b/src/snapshots/eww_config__test-16.snap @@ -0,0 +1,8 @@ +--- +source: src/lib.rs +expression: "p.parse(\"\\\"h\\\\\\\"i\\\"\")" + +--- +Ok( + Str<0..6>(h\"i), +) diff --git a/src/snapshots/eww_config__test-2.snap b/src/snapshots/eww_config__test-2.snap index f16a309..dd84a41 100644 --- a/src/snapshots/eww_config__test-2.snap +++ b/src/snapshots/eww_config__test-2.snap @@ -1,16 +1,12 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(12)\")" --- Ok( - List( - 0..4, + List<0..4>( [ - Number( - 1..3, - 12, - ), + Number<1..3>(12), ], ), ) diff --git a/src/snapshots/eww_config__test-3.snap b/src/snapshots/eww_config__test-3.snap index 99b52c6..5f7b32c 100644 --- a/src/snapshots/eww_config__test-3.snap +++ b/src/snapshots/eww_config__test-3.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(1 2)\")" --- Ok( - List( - 0..5, + List<0..5>( [ - Number( - 1..2, - 1, - ), - Number( - 3..4, - 2, - ), + Number<1..2>(1), + Number<3..4>(2), ], ), ) diff --git a/src/snapshots/eww_config__test-4.snap b/src/snapshots/eww_config__test-4.snap index 6ecf27d..8ce142b 100644 --- a/src/snapshots/eww_config__test-4.snap +++ b/src/snapshots/eww_config__test-4.snap @@ -1,24 +1,14 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(1 :foo 1)\")" --- Ok( - List( - 0..10, + List<0..10>( [ - Number( - 1..2, - 1, - ), - Keyword( - 3..7, - ":foo", - ), - Number( - 8..9, - 1, - ), + Number<1..2>(1), + Number<3..7>(:foo), + Number<8..9>(1), ], ), ) diff --git a/src/snapshots/eww_config__test-5.snap b/src/snapshots/eww_config__test-5.snap index ff6efe3..9db3361 100644 --- a/src/snapshots/eww_config__test-5.snap +++ b/src/snapshots/eww_config__test-5.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(:foo 1)\")" --- Ok( - List( - 0..8, + List<0..8>( [ - Keyword( - 1..5, - ":foo", - ), - Number( - 6..7, - 1, - ), + Number<1..5>(:foo), + Number<6..7>(1), ], ), ) diff --git a/src/snapshots/eww_config__test-6.snap b/src/snapshots/eww_config__test-6.snap index 919dd49..f368f33 100644 --- a/src/snapshots/eww_config__test-6.snap +++ b/src/snapshots/eww_config__test-6.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(:foo->: 1)\")" --- Ok( - List( - 0..11, + List<0..11>( [ - Keyword( - 1..8, - ":foo->:", - ), - Number( - 9..10, - 1, - ), + Number<1..8>(:foo->:), + Number<9..10>(1), ], ), ) diff --git a/src/snapshots/eww_config__test-7.snap b/src/snapshots/eww_config__test-7.snap index 0c038c5..eb63df2 100644 --- a/src/snapshots/eww_config__test-7.snap +++ b/src/snapshots/eww_config__test-7.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(foo 1)\")" --- Ok( - List( - 0..7, + List<0..7>( [ - Symbol( - 1..4, - "foo", - ), - Number( - 5..6, - 1, - ), + Symbol<1..4>(foo), + Number<5..6>(1), ], ), ) diff --git a/src/snapshots/eww_config__test-8.snap b/src/snapshots/eww_config__test-8.snap index eec1f65..ee21f3e 100644 --- a/src/snapshots/eww_config__test-8.snap +++ b/src/snapshots/eww_config__test-8.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"(lol😄 1)\")" --- Ok( - List( - 0..11, + List<0..11>( [ - Symbol( - 1..8, - "lol😄", - ), - Number( - 9..10, - 1, - ), + Symbol<1..8>(lol😄), + Number<9..10>(1), ], ), ) diff --git a/src/snapshots/eww_config__test-9.snap b/src/snapshots/eww_config__test-9.snap index ce6c9db..edc1cb8 100644 --- a/src/snapshots/eww_config__test-9.snap +++ b/src/snapshots/eww_config__test-9.snap @@ -1,20 +1,13 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(r#\"(test \"hi\")\"#)" --- Ok( - List( - 0..11, + List<0..11>( [ - Symbol( - 1..5, - "test", - ), - Str( - 6..10, - "hi", - ), + Symbol<1..5>(test), + Str<6..10>(hi), ], ), ) diff --git a/src/snapshots/eww_config__test.snap b/src/snapshots/eww_config__test.snap index 2547c26..8c42a6b 100644 --- a/src/snapshots/eww_config__test.snap +++ b/src/snapshots/eww_config__test.snap @@ -1,11 +1,8 @@ --- -source: src/main.rs +source: src/lib.rs expression: "p.parse(\"1\")" --- Ok( - Number( - 0..1, - 1, - ), + Number<0..1>(1), )