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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
use crate::{Next, linter::registry::ResLintRegistry};
use mingling::{
Grouped, LazyRes, Routable, ShellContext, Suggest, SuggestItem,
macros::{
arg, buffer, chain, completion, dispatcher, metadata, pack, pack_err, r_println, renderer,
routeify,
},
metadata::Description,
picker::EntryPicker,
};
dispatcher!("explain");
#[metadata(EntryExplain)]
pub fn desc_explain() -> Description {
"Explain the meaning of the specified Lint".into()
}
pack!(StateExplainLint = String);
pack_err!(ErrorNoExplainLintProvided);
pack_err!(ErrorNoSuchLint = String);
#[derive(Debug, Default, Grouped)]
pub struct ResultExplainLint {
pub lint_name: String,
pub title: String,
pub summary: String,
pub active_on: String,
pub author: String,
pub default: String,
}
#[chain(routeify)]
pub fn handle_explain(args: EntryExplain) -> Next {
let lint_name = args
.pick_or_route(&arg![String], || {
ErrorNoExplainLintProvided::default().to_chain()
})
.to_result()?;
StateExplainLint::new(lint_name).into()
}
#[chain]
pub fn handle_state_explain_lint(
p: StateExplainLint,
registry: &mut LazyRes<ResLintRegistry>,
) -> Next {
let registry = registry.get_ref();
let lint_name = p.inner;
let Some(entry) = registry.lints.iter().find(|l| l.name == lint_name) else {
return ErrorNoSuchLint::new(lint_name).to_chain();
};
ResultExplainLint {
lint_name: entry.name.clone(),
title: entry.title.clone(),
summary: entry.summary.clone(),
active_on: entry.metadata.active_on.clone(),
author: entry.metadata.author.clone(),
default: entry.metadata.default.clone(),
}
.to_chain()
}
#[renderer(buffer)]
pub fn render_explain_lint(r: ResultExplainLint) {
r_println!("{}", r.title);
r_println!("");
r_println!(" Name : #[mlint[{}({})]", r.default, r.lint_name);
r_println!(" Author : {}", r.author);
r_println!("");
r_println!("{}", r.summary);
}
#[renderer(buffer)]
pub fn render_error_no_explain_lint_provided(_: ErrorNoExplainLintProvided) {
r_println!("No lint name provided");
r_println!("");
r_println!("Usage: mling explain <LINT>");
}
#[renderer(buffer)]
pub fn render_error_no_such_lint(err: ErrorNoSuchLint, registry: &mut LazyRes<ResLintRegistry>) {
let registry = registry.get_ref();
r_println!("No such lint: \"{}\"", err.info);
r_println!("");
r_println!("Available lints:");
for entry in registry.lints.iter() {
r_println!(" {}", entry.name);
}
}
#[completion(EntryExplain)]
pub fn complete_explain(ctx: &ShellContext, registry: &mut LazyRes<ResLintRegistry>) -> Suggest {
let registry = registry.get_ref();
if ctx.previous_word != "explain" {
return Suggest::FileCompletion;
}
let lints: Vec<String> = registry.lints.iter().map(|l| l.name.clone()).collect();
let mut suggest = Suggest::new();
for lint in lints {
suggest.insert(SuggestItem::Simple(lint));
}
suggest
}
|