1#![deny(unused_must_use)]23mod binary;4mod event;5mod lex;6mod marker;7mod parser;8mod string_block;9mod token_set;10mod unary;1112#[cfg(test)]13mod tests {14 use miette::{Diagnostic, GraphicalReportHandler, LabeledSpan};15 use thiserror::Error;1617 use crate::parser::parse;1819 #[derive(Debug, Error)]20 #[error("syntax error")]21 struct MyDiagnostic {22 code: String,23 spans: Vec<LabeledSpan>,24 }25 impl Diagnostic for MyDiagnostic {26 fn code<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {27 None28 }2930 fn severity(&self) -> Option<miette::Severity> {31 None32 }3334 fn help<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {35 None36 }3738 fn url<'a>(&'a self) -> Option<Box<dyn std::fmt::Display + 'a>> {39 None40 }4142 fn source_code(&self) -> Option<&dyn miette::SourceCode> {43 Some(&self.code)44 }4546 fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {47 Some(Box::new(self.spans.clone().into_iter()))48 }4950 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {51 None52 }53 }5455 fn process(text: &str) -> String {56 use std::fmt::Write;57 let mut out = String::new();58 let node = parse(text);59 write!(out, "{:#?}", node.syntax()).unwrap();60 if !node.errors.is_empty() && !text.is_empty() {61 writeln!(out, "===").unwrap();62 for err in &node.errors {63 writeln!(out, "{:?}", err).unwrap();64 }65 let diag = MyDiagnostic {66 code: text.to_string(),67 spans: node.errors.into_iter().map(|e| e.into()).collect(),68 };6970 let handler = GraphicalReportHandler::new();7172 write!(out, "===").unwrap();73 handler.render_report(&mut out, &diag).unwrap();74 }75 out76 }77 macro_rules! mk_test {78 ($($name:ident => $test:expr)+) => {$(79 #[test]80 fn $name() {81 let src = indoc::indoc!($test);82 let result = process(&src);83 insta::assert_snapshot!(stringify!($name), result, src);8485 }86 )+};87 }88 mk_test!(89 empty => r#" "#90 function => r#"91 function(a, b = 1) a + b92 "#93 function_error_no_value => r#"94 function(a, b = ) a + b95 "#96 function_error_rparen => r#"97 function(a, b98 "#99 function_error_body => r#"100 function(a, b)101 "#102 local_novalue => r#"103 local a =104 "#105 local_no_value_recovery => r#"106 local a =107 local b = 3;108 1109 "#110111 array_comp => r#"112 [a for a in [1, 2, 3]]113 "#114 array_comp_incompatible_with_multiple_elems => r#"115 [a for a in [1, 2, 3], b]116 "#117118 no_rhs => r#"119 a +120 "#121 no_lhs => r#"122 + 2123 "#124 no_operator => "125 2 2126 "127128 named_before_positional => "129 a(1, 2, b=4, 3, 5, k = 12, 6)130 "131132 wrong_field_end => "133 {134 a: 1;135 b: 2;136 }137 "138 );139}