1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// What: `use forbidden_strings::run_cli_from_env;` imports the
// public lib entry point. The crate's library target is
// named `forbidden_strings` (underscores; the `[[bin]]`
// name keeps the hyphen for the on-disk binary). The lib
// owns argv parsing, env var reads, ruleset loading, the
// parallel scan, and stderr emission; this file just
// translates its return into the OS exit code.
// Why: Move every interesting branch out of `main`. Tests
// (`tests/integration.rs`) still drive the binary as a
// subprocess, but additional fuzz targets and unit tests
// can now exercise `run_cli_from_env` (and the helpers it
// re-exports through the `fuzzing` Cargo feature) without
// spawning a child process.
// TS map: `import { runCliFromEnv } from "./lib";`.
//
// In TS you'd write (pseudocode):
// ```ts
// import { runCliFromEnv } from "./lib";
// ```
use run_cli_from_env;
// What: `use std::process::ExitCode;` imports the typed wrapper
// for OS exit codes. Returning `ExitCode` from `main` is
// the idiomatic way to set the exit status from Rust.
// Why: We need it to translate `run_cli_from_env`'s `i32`
// into the typed value `main` returns.
// TS map: No direct equivalent; Node uses `process.exit(N)` or
// `process.exitCode = N`.
//
// In TS you'd write (pseudocode):
// ```ts
// // No type; just a number.
// ```
use ExitCode;
// What: `fn main() -> ExitCode` is the program entry point. It
// dispatches to `run_cli_from_env` and converts the
// returned `Result<i32, String>` into an `ExitCode`. The
// `Err` arm prints the catastrophic error to stderr with
// a fixed `forbidden-strings:` prefix and exits 2; the
// lib never produces an `Err` today (every recoverable
// error path eprintln's and returns `Ok(2)`), but the
// shape is reserved so future panics or unwrap-failures
// in the lib have somewhere to surface.
// Why: Keep `main` to a five-line wrapper so the lib is the
// sole carrier of business logic, and tests can drive
// every code path without spawning a subprocess.
// TS map: `process.exit(await runCliFromEnv());` plus a top-level
// `try { ... } catch (e) { console.error(...); process.exit(2); }`.
//
// In TS you'd write (pseudocode):
// ```ts
// try { process.exit(await runCliFromEnv()); }
// catch (e) { console.error(`forbidden-strings: ${e}`); process.exit(2); }
// ```