aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-08-06 17:23:34 +0800
committer魏曹先生 <1992414357@qq.com>2026-08-07 16:57:24 +0800
commit6df0dd50b14f8fb07da2fe78d71311e6b127c6aa (patch)
tree09b0afe787cecb37f31f857f8b36bd2859035dcd
parent0e15654b14d064040e6e6ddca541a1441a5f1e4e (diff)
feat(linter): refactor lint registry into program resource
Extract lint registry loading from cmd_explain into a shared program-level resource initialized via setup.
-rw-r--r--mingling_cli/src/linter.rs2
-rw-r--r--mingling_cli/src/linter/cmd_explain.rs63
-rw-r--r--mingling_cli/src/linter/registry.rs33
-rw-r--r--mingling_cli/src/main.rs14
4 files changed, 58 insertions, 54 deletions
diff --git a/mingling_cli/src/linter.rs b/mingling_cli/src/linter.rs
index 4916eba..30d79de 100644
--- a/mingling_cli/src/linter.rs
+++ b/mingling_cli/src/linter.rs
@@ -3,4 +3,4 @@ pub mod cmd_lint;
pub mod cmd_ra_lints;
pub mod mlint_attr;
pub mod mlint_report;
-
+pub mod registry;
diff --git a/mingling_cli/src/linter/cmd_explain.rs b/mingling_cli/src/linter/cmd_explain.rs
index d1dffc5..f0a7571 100644
--- a/mingling_cli/src/linter/cmd_explain.rs
+++ b/mingling_cli/src/linter/cmd_explain.rs
@@ -1,5 +1,6 @@
+use crate::{Next, linter::registry::LintRegistry};
use mingling::{
- Grouped, Routable, ShellContext, StructuralData, Suggest, SuggestItem,
+ Grouped, LazyRes, Routable, ShellContext, StructuralData, Suggest, SuggestItem,
macros::{
arg, buffer, chain, completion, dispatcher, metadata, pack, pack_err_structural, r_println,
renderer, routeify,
@@ -7,10 +8,7 @@ use mingling::{
metadata::Description,
picker::EntryPicker,
};
-use serde::{Deserialize, Serialize};
-use std::sync::OnceLock;
-
-use crate::Next;
+use serde::Serialize;
dispatcher!("explain");
@@ -43,43 +41,14 @@ pub fn handle_explain(args: EntryExplain) -> Next {
StateExplainLint::new(lint_name).into()
}
-/// Mirror of the lint registry JSON generated by `build.rs` (`registry.json`).
-#[derive(Debug, Deserialize)]
-struct LintRegistry {
- lints: Vec<LintEntry>,
-}
-
-#[derive(Debug, Deserialize)]
-struct LintEntry {
- name: String,
- title: String,
- summary: String,
- metadata: LintMetadata,
-}
-
-#[derive(Debug, Deserialize)]
-struct LintMetadata {
- active_on: String,
- author: String,
- default: String,
-}
-
-/// The lint registry, embedded at compile time via `include_str!`.
-///
-/// `registry.json` is regenerated by `build.rs` on every build, so the
-/// embedded copy always reflects the lints in `src/lints/`.
-fn lint_registry() -> &'static LintRegistry {
- static REGISTRY: OnceLock<LintRegistry> = OnceLock::new();
- REGISTRY.get_or_init(|| {
- serde_json::from_str(include_str!("../../registry.json"))
- .expect("failed to parse embedded registry.json")
- })
-}
-
#[chain]
-pub fn handle_state_explain_lint(p: StateExplainLint) -> Next {
+pub fn handle_state_explain_lint(
+ p: StateExplainLint,
+ registry: &mut LazyRes<LintRegistry>,
+) -> Next {
+ let registry = registry.get_ref();
let lint_name = p.inner;
- let Some(entry) = lint_registry().lints.iter().find(|l| l.name == lint_name) else {
+ let Some(entry) = registry.lints.iter().find(|l| l.name == lint_name) else {
return ErrorNoSuchLint::new(lint_name).to_chain();
};
ResultExplainLint {
@@ -111,25 +80,23 @@ pub fn render_error_no_explain_lint_provided(_: ErrorNoExplainLintProvided) {
}
#[renderer(buffer)]
-pub fn render_error_no_such_lint(err: ErrorNoSuchLint) {
+pub fn render_error_no_such_lint(err: ErrorNoSuchLint, registry: &mut LazyRes<LintRegistry>) {
+ let registry = registry.get_ref();
r_println!("No such lint: \"{}\"", err.info);
r_println!("");
r_println!("Available lints:");
- for entry in &lint_registry().lints {
+ for entry in registry.lints.iter() {
r_println!(" {}", entry.name);
}
}
#[completion(EntryExplain)]
-pub fn complete_explain(ctx: &ShellContext) -> Suggest {
+pub fn complete_explain(ctx: &ShellContext, registry: &mut LazyRes<LintRegistry>) -> Suggest {
+ let registry = registry.get_ref();
if ctx.previous_word != "explain" {
return Suggest::FileCompletion;
}
- let lints: Vec<String> = lint_registry()
- .lints
- .iter()
- .map(|l| l.name.clone())
- .collect();
+ 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));
diff --git a/mingling_cli/src/linter/registry.rs b/mingling_cli/src/linter/registry.rs
new file mode 100644
index 0000000..5241c29
--- /dev/null
+++ b/mingling_cli/src/linter/registry.rs
@@ -0,0 +1,33 @@
+use mingling::{LazyInit, Program, macros::program_setup};
+use serde::Deserialize;
+
+use crate::ThisProgram;
+
+#[derive(Debug, Default, Clone, Deserialize)]
+pub struct LintRegistry {
+ pub lints: Vec<LintEntry>,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct LintEntry {
+ pub name: String,
+ pub title: String,
+ pub summary: String,
+ pub metadata: LintMetadata,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct LintMetadata {
+ pub active_on: String,
+ pub author: String,
+ pub default: String,
+}
+
+#[program_setup]
+pub fn lint_registry_setup(p: &mut Program<ThisProgram>) {
+ p.with_resource(LintRegistry::lazy_init(|| {
+ let registry: LintRegistry = serde_json::from_str(include_str!("../../registry.json"))
+ .expect("failed to parse embedded registry.json");
+ registry
+ }));
+}
diff --git a/mingling_cli/src/main.rs b/mingling_cli/src/main.rs
index da30861..7c71bcd 100644
--- a/mingling_cli/src/main.rs
+++ b/mingling_cli/src/main.rs
@@ -1,8 +1,11 @@
-use crate::metadata::{
- MinglingMetadataSetup,
- setup::{
- ARG_ALL_FEATURES, ARG_FEATURES, ARG_MANIFEST_PATH, ARG_MESSAGE_FORMAT,
- ARG_NO_DEFAULT_FEATURES, ARG_NO_DEPS,
+use crate::{
+ linter::registry::LintRegistrySetup,
+ metadata::{
+ MinglingMetadataSetup,
+ setup::{
+ ARG_ALL_FEATURES, ARG_FEATURES, ARG_MANIFEST_PATH, ARG_MESSAGE_FORMAT,
+ ARG_NO_DEFAULT_FEATURES, ARG_NO_DEPS,
+ },
},
};
use mingling::{
@@ -34,6 +37,7 @@ async fn main() {
program.with_setup(ExitCodeSetup::default());
program.with_setup(MinglingMetadataSetup);
+ program.with_setup(LintRegistrySetup);
// Exec
program.exec_and_exit().await;