wowlab_tidy/languages/rust/rules/api/
forbidden_deps.rs1use crate::{Example, FileCtx, Violation, infra::parse, violation};
2
3#[rustfmt::skip]
4const EXAMPLES: &[Example] = &[
5 Example {
6 label: "std::net import",
7 code: "use std::net::TcpStream;",
8 pass: false,
9 },
10 Example {
11 label: "std::thread import",
12 code: "use std::thread;",
13 pass: false,
14 },
15 Example {
16 label: "normal import",
17 code: "use std::collections::HashMap;",
18 pass: true,
19 },
20 Example {
21 label: "comment with forbidden",
22 code: "// use std::thread::spawn",
23 pass: true,
24 },
25 Example {
26 label: "forbidden in string literal",
27 code: r#"let msg = "std::net is unavailable";"#,
28 pass: true,
29 },
30];
31
32crate::line_rule!(
33 forbidden_deps,
34 "Ban `std::net` and `std::thread` in WASM-targeted crates.",
35 "std::net and std::thread are not available in WASM. Using them in engine code breaks the web build.",
36 High,
37);
38
39const FORBIDDEN_MODULES: &[&str] = &["std::net", "std::thread"];
40
41fn check_forbidden_deps(ctx: &FileCtx<'_>) -> Vec<Violation> {
42 let mut out = Vec::new();
43
44 for (i, line) in ctx.lines.iter().enumerate() {
45 let lineno = i + 1;
46 let trimmed = line.trim();
47
48 if parse::is_comment(trimmed) {
49 continue;
50 }
51
52 for module in FORBIDDEN_MODULES {
53 if crate::infra::helpers::contains_outside_strings(line, module) {
54 out.push(violation(
55 ctx.rel,
56 lineno,
57 format!("{module} is forbidden in WASM-targeted crates"),
58 ));
59 }
60 }
61 }
62
63 out
64}
65
66crate::tidy_test!(check_forbidden_deps, {
67 crate::example_tests!(EXAMPLES, check_forbidden_deps);
68});