Skip to main content

wowlab_tidy/languages/rust/rules/tests/
mod.rs

1mod 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}