wowlab_tidy/languages/rust/rules/tests/
mod.rs1mod consecutive_field_asserts;
2mod expect_in_result_test;
3mod gtest_required;
4mod indexed_element_asserts;
5mod manual_float_epsilon;
6
7use ra_ap_syntax::{
8 AstNode, Edition, SourceFile,
9 ast::{self},
10};
11
12fn macro_name(call: &ast::MacroCall) -> Option<String> {
13 call.path()?
14 .segment()?
15 .syntax()
16 .last_token()
17 .map(|token| token.text().to_owned())
18}
19
20fn first_macro_argument(call: &ast::MacroCall) -> Option<ast::Expr> {
21 let tree = call.token_tree()?;
22 let mut source = String::new();
23
24 for element in tree.syntax().children_with_tokens() {
25 if element
26 .as_token()
27 .is_some_and(|token| matches!(token.text(), "(" | "[" | "{"))
28 {
29 continue;
30 }
31
32 if element
33 .as_token()
34 .is_some_and(|token| matches!(token.text(), ")" | "]" | "}" | ","))
35 {
36 break;
37 }
38
39 source.push_str(&element.to_string());
40 }
41
42 let parse = SourceFile::parse(
43 &format!("fn fixture() {{ {source}; }}"),
44 Edition::Edition2024,
45 );
46
47 parse
48 .errors()
49 .is_empty()
50 .then(|| parse.tree())?
51 .syntax()
52 .descendants()
53 .filter_map(ast::ExprStmt::cast)
54 .find_map(|statement| statement.expr())
55}
56
57fn statement_macro(statement: &ast::Stmt) -> Option<ast::MacroCall> {
58 let ast::Stmt::ExprStmt(statement) = statement else {
59 return None;
60 };
61 let ast::Expr::MacroExpr(expression) = statement.expr()? else {
62 return None;
63 };
64
65 expression.macro_call()
66}