diff options
author | Akshay <[email protected]> | 2021-09-15 11:49:58 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-09-15 11:49:58 +0100 |
commit | c91c2ae1398e4f567ee5e4c50a1da35a9b65919b (patch) | |
tree | 71532adbed436fd99e13d81e4ac76a27f82ff7f7 /bin/src/main.rs | |
parent | 2ee7db0b3b6df787c7e62d3614f97a0e45d12a12 (diff) |
init cli entrypoint
Diffstat (limited to 'bin/src/main.rs')
-rw-r--r-- | bin/src/main.rs | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/bin/src/main.rs b/bin/src/main.rs index e7a11a9..ae45bfe 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs | |||
@@ -1,3 +1,82 @@ | |||
1 | use std::{ | ||
2 | env, fs, | ||
3 | path::{Path, PathBuf}, | ||
4 | }; | ||
5 | |||
6 | use anyhow::{Context, Result}; | ||
7 | use ariadne::{Color, Fmt, Label, Report as CliReport, ReportKind as CliReportKind, Source}; | ||
8 | use lib::{Report, LINTS}; | ||
9 | use rnix::WalkEvent; | ||
10 | |||
11 | fn analyze(file: &str) -> Result<Vec<Report>> { | ||
12 | let parsed = rnix::parse(file).as_result()?; | ||
13 | |||
14 | Ok(parsed | ||
15 | .node() | ||
16 | .preorder_with_tokens() | ||
17 | .filter_map(|event| match event { | ||
18 | WalkEvent::Enter(child) => LINTS.get(&child.kind()).map(|rules| { | ||
19 | rules | ||
20 | .iter() | ||
21 | .filter_map(|rule| rule.validate(&child)) | ||
22 | .collect::<Vec<_>>() | ||
23 | }), | ||
24 | _ => None, | ||
25 | }) | ||
26 | .flatten() | ||
27 | .collect()) | ||
28 | } | ||
29 | |||
30 | fn print_report(report: Report, file_src: &str, file_path: &Path) -> Result<()> { | ||
31 | let src_id = file_path.to_str().unwrap_or("<unknown>"); | ||
32 | let offset = report | ||
33 | .diagnostics | ||
34 | .iter() | ||
35 | .map(|d| d.at.start().into()) | ||
36 | .min() | ||
37 | .unwrap_or(0usize); | ||
38 | report | ||
39 | .diagnostics | ||
40 | .iter() | ||
41 | .fold( | ||
42 | CliReport::build(CliReportKind::Warning, src_id, offset), | ||
43 | |cli_report, diagnostic| { | ||
44 | let range = { | ||
45 | let at = diagnostic.at; | ||
46 | at.start().into()..at.end().into() | ||
47 | }; | ||
48 | cli_report.with_label( | ||
49 | Label::new((src_id, range)) | ||
50 | .with_message(diagnostic.message.as_str().fg(Color::Yellow)), | ||
51 | ) | ||
52 | }, | ||
53 | ) | ||
54 | .finish() | ||
55 | .print((src_id, Source::from(file_src))) | ||
56 | .context("failed to print report to stdout") | ||
57 | } | ||
58 | |||
59 | fn _main() -> Result<()> { | ||
60 | let args = env::args(); | ||
61 | for (file_src, file_path, reports) in args | ||
62 | .map(|s| PathBuf::from(&s)) | ||
63 | .filter(|p| p.is_file()) | ||
64 | .filter_map(|path| { | ||
65 | let s = fs::read_to_string(&path).ok()?; | ||
66 | analyze(&s) | ||
67 | .map(|analysis_result| (s, path, analysis_result)) | ||
68 | .ok() | ||
69 | }) | ||
70 | { | ||
71 | for r in reports { | ||
72 | print_report(r, &file_src, &file_path)? | ||
73 | } | ||
74 | } | ||
75 | Ok(()) | ||
76 | } | ||
1 | fn main() { | 77 | fn main() { |
2 | println!("Hello, world!"); | 78 | match _main() { |
79 | Err(e) => eprintln!("{}", e), | ||
80 | _ => {} | ||
81 | } | ||
3 | } | 82 | } |