nginx_lint_plugin/
native.rs1use crate::types::{
32 Fix as PluginFix, LintError as PluginLintError, Plugin, Severity as PluginSeverity,
33};
34use nginx_lint_common::linter::{
35 Fix as CommonFix, LintError as CommonLintError, LintRule, Severity as CommonSeverity,
36};
37use nginx_lint_common::parser::ast::Config;
38use std::path::Path;
39
40fn convert_fix(fix: PluginFix) -> CommonFix {
42 CommonFix {
43 line: fix.line,
44 old_text: fix.old_text,
45 new_text: fix.new_text,
46 delete_line: fix.delete_line,
47 insert_after: fix.insert_after,
48 start_offset: fix.start_offset,
49 end_offset: fix.end_offset,
50 }
51}
52
53fn convert_lint_error(err: PluginLintError) -> CommonLintError {
55 let severity = match err.severity {
56 PluginSeverity::Error => CommonSeverity::Error,
57 PluginSeverity::Warning => CommonSeverity::Warning,
58 };
59
60 let mut common = CommonLintError::new(&err.rule, &err.category, &err.message, severity);
61
62 if let (Some(line), Some(column)) = (err.line, err.column) {
63 common = common.with_location(line, column);
64 } else if let Some(line) = err.line {
65 common = common.with_location(line, 1);
66 }
67
68 for fix in err.fixes {
69 common = common.with_fix(convert_fix(fix));
70 }
71
72 common
73}
74
75pub struct NativePluginRule<P: Plugin> {
80 plugin: P,
81 name: &'static str,
82 category: &'static str,
83 description: &'static str,
84 severity: Option<&'static str>,
85 why: Option<&'static str>,
86 bad_example: Option<&'static str>,
87 good_example: Option<&'static str>,
88 references: Option<Vec<String>>,
89 min_nginx_version: Option<&'static str>,
90 max_nginx_version: Option<&'static str>,
91}
92
93impl<P: Plugin> Default for NativePluginRule<P> {
94 fn default() -> Self {
95 Self::new()
96 }
97}
98
99impl<P: Plugin> NativePluginRule<P> {
100 pub fn new() -> Self {
101 Self::with_plugin(P::default())
102 }
103
104 pub fn with_plugin(plugin: P) -> Self {
106 let spec = plugin.spec();
107
108 let name: &'static str = Box::leak(spec.name.into_boxed_str());
110 let category: &'static str = Box::leak(spec.category.into_boxed_str());
111 let description: &'static str = Box::leak(spec.description.into_boxed_str());
112 let severity: Option<&'static str> = spec.severity.map(|s| &*Box::leak(s.into_boxed_str()));
113 let why: Option<&'static str> = spec.why.map(|s| &*Box::leak(s.into_boxed_str()));
114 let bad_example: Option<&'static str> =
115 spec.bad_example.map(|s| &*Box::leak(s.into_boxed_str()));
116 let good_example: Option<&'static str> =
117 spec.good_example.map(|s| &*Box::leak(s.into_boxed_str()));
118 let references = spec.references;
119 let min_nginx_version: Option<&'static str> = spec
120 .min_nginx_version
121 .map(|s| &*Box::leak(s.into_boxed_str()));
122 let max_nginx_version: Option<&'static str> = spec
123 .max_nginx_version
124 .map(|s| &*Box::leak(s.into_boxed_str()));
125
126 Self {
127 plugin,
128 name,
129 category,
130 description,
131 severity,
132 why,
133 bad_example,
134 good_example,
135 references,
136 min_nginx_version,
137 max_nginx_version,
138 }
139 }
140}
141
142impl<P: Plugin + Send + Sync> LintRule for NativePluginRule<P> {
143 fn name(&self) -> &'static str {
144 self.name
145 }
146
147 fn category(&self) -> &'static str {
148 self.category
149 }
150
151 fn description(&self) -> &'static str {
152 self.description
153 }
154
155 fn check(&self, config: &Config, path: &Path) -> Vec<CommonLintError> {
156 let path_str = path.to_string_lossy();
157 let errors = self.plugin.check(config, &path_str);
158 errors.into_iter().map(convert_lint_error).collect()
159 }
160
161 fn severity(&self) -> Option<&str> {
162 self.severity
163 }
164
165 fn why(&self) -> Option<&str> {
166 self.why
167 }
168
169 fn bad_example(&self) -> Option<&str> {
170 self.bad_example
171 }
172
173 fn good_example(&self) -> Option<&str> {
174 self.good_example
175 }
176
177 fn references(&self) -> Option<Vec<String>> {
178 self.references.clone()
179 }
180
181 fn min_nginx_version(&self) -> Option<&str> {
182 self.min_nginx_version
183 }
184
185 fn max_nginx_version(&self) -> Option<&str> {
186 self.max_nginx_version
187 }
188}