1 use syntax::{ast, AstNode};
7 fn check(macro_body: &str) {
8 let m = parse_macro_arm(macro_body);
12 check("($i:ident) => ()");
13 check("($(x),*) => ()");
14 check("($(x)_*) => ()");
15 check("($(x)i*) => ()");
16 check("($($i:ident)*) => ($_)");
17 check("($($true:ident)*) => ($true)");
18 check("($($false:ident)*) => ($false)");
23 fn test_invalid_arms() {
24 fn check(macro_body: &str, err: ParseError) {
25 let m = parse_macro_arm(macro_body);
26 assert_eq!(m, Err(err));
28 check("invalid", ParseError::Expected("expected subtree".into()));
30 check("$i:ident => ()", ParseError::Expected("expected subtree".into()));
31 check("($i:ident) ()", ParseError::Expected("expected `=`".into()));
32 check("($($i:ident)_) => ()", ParseError::InvalidRepeat);
34 check("($i) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
35 check("($i:) => ($i)", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
36 check("($i:_) => ()", ParseError::UnexpectedToken("bad fragment specifier 1".into()));
39 fn parse_macro_arm(arm_definition: &str) -> Result<crate::MacroRules, ParseError> {
40 let macro_definition = format!(" macro_rules! m {{ {} }} ", arm_definition);
41 let source_file = ast::SourceFile::parse(¯o_definition).ok().unwrap();
42 let macro_definition =
43 source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap();
45 let (definition_tt, _) =
46 syntax_node_to_token_tree(macro_definition.token_tree().unwrap().syntax());
47 crate::MacroRules::parse(&definition_tt)