From c3cd11149d39802c431381d8f4d685581ab8c0f5 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Thu, 6 Aug 2026 17:23:34 +0800 Subject: feat(linter): refactor lint registry into program resource Extract lint registry loading from cmd_explain into a shared program-level resource initialized via setup. --- mingling_cli/src/linter/cmd_explain.rs | 63 ++++++++-------------------------- 1 file changed, 15 insertions(+), 48 deletions(-) (limited to 'mingling_cli/src/linter/cmd_explain.rs') 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, -} - -#[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 = 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, +) -> 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) { + 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) -> Suggest { + let registry = registry.get_ref(); if ctx.previous_word != "explain" { return Suggest::FileCompletion; } - let lints: Vec = lint_registry() - .lints - .iter() - .map(|l| l.name.clone()) - .collect(); + let lints: Vec = registry.lints.iter().map(|l| l.name.clone()).collect(); let mut suggest = Suggest::new(); for lint in lints { suggest.insert(SuggestItem::Simple(lint)); -- cgit