Skip to main content

max / makenotwork

docengine: adopt universal clippy/lint baseline; warnings to zero Add the shared pedantic + unreachable_pub baseline ([lints] block). Cleared all warnings: #[must_use] on the 10 Renderer builder setters (return_self_not_must_use), by-value self on the Copy SanitizePreset methods (trivially_copy_pass_by_ref), and a writeln! in render_toc_html (format_push_string). clippy --fix handled the rest. clippy --all-targets clean, cargo fmt clean, 96 tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-23 13:04 UTC
Commit: 7ebcaa6c9a241eeef42d77176f0e16349310af39
Parent: 6836e92
6 files changed, +58 insertions, -17 deletions
@@ -31,3 +31,35 @@ tempfile = "3"
31 31 [[bin]]
32 32 name = "substitute_dir"
33 33 required-features = ["assumptions"]
34 +
35 + [lints.rust]
36 + unused = "warn"
37 + unreachable_pub = "warn"
38 +
39 + [lints.clippy]
40 + pedantic = { level = "warn", priority = -1 }
41 + # Allow-list tuned from a measured breakdown across server/multithreaded/pter
42 + # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything
43 + # else in `pedantic` stays a warning. Keep this block identical across repos.
44 + module_name_repetitions = "allow"
45 + # Doc lints — no docs-completeness push underway.
46 + missing_errors_doc = "allow"
47 + missing_panics_doc = "allow"
48 + doc_markdown = "allow"
49 + # Numeric casts — endemic and mostly intentional in size/byte math.
50 + cast_possible_truncation = "allow"
51 + cast_sign_loss = "allow"
52 + cast_precision_loss = "allow"
53 + cast_possible_wrap = "allow"
54 + cast_lossless = "allow"
55 + # Subjective structure/style nags — high churn, low signal.
56 + must_use_candidate = "allow"
57 + too_many_lines = "allow"
58 + struct_excessive_bools = "allow"
59 + similar_names = "allow"
60 + items_after_statements = "allow"
61 + single_match_else = "allow"
62 + # Frequent false-positives in TUI/router-heavy code — added from the buckets breakdown.
63 + match_same_arms = "allow"
64 + unnecessary_wraps = "allow"
65 + type_complexity = "allow"
@@ -1,6 +1,6 @@
1 1 /// Strip inline code (backtick) and fenced code blocks, replacing with spaces.
2 2 #[cfg_attr(not(any(feature = "mentions", test)), allow(dead_code))]
3 - pub fn strip_code_spans(input: &str) -> String {
3 + pub(crate) fn strip_code_spans(input: &str) -> String {
4 4 let mut out = String::with_capacity(input.len());
5 5 let mut chars = input.chars().peekable();
6 6
@@ -37,7 +37,7 @@ pub fn strip_code_spans(input: &str) -> String {
37 37 }
38 38
39 39 /// Return byte ranges of inline code spans and fenced code blocks.
40 - pub fn code_span_ranges(input: &str) -> Vec<(usize, usize)> {
40 + pub(crate) fn code_span_ranges(input: &str) -> Vec<(usize, usize)> {
41 41 let mut ranges = Vec::new();
42 42 let bytes = input.as_bytes();
43 43 let len = bytes.len();
@@ -137,7 +137,7 @@ mod tests {
137 137 // Distinguishes `*` from `+` (3+2=5) and pins `+ skipped` vs `- skipped`.
138 138 let result = strip_code_spans("```ab```");
139 139 let spaces = result.chars().filter(|c| *c == ' ').count();
140 - assert_eq!(spaces, 9, "expected 3*2 + 3 = 9 spaces, got {:?}", result);
140 + assert_eq!(spaces, 9, "expected 3*2 + 3 = 9 spaces, got {result:?}");
141 141 }
142 142
143 143 #[test]
@@ -146,7 +146,7 @@ mod tests {
146 146 // Distinguishes `tick_count * 2` from `tick_count + 2` (3 vs 4).
147 147 let result = strip_code_spans("`a`");
148 148 let spaces = result.chars().filter(|c| *c == ' ').count();
149 - assert_eq!(spaces, 4, "expected 1*2 + 2 = 4 spaces, got {:?}", result);
149 + assert_eq!(spaces, 4, "expected 1*2 + 2 = 4 spaces, got {result:?}");
150 150 }
151 151
152 152 #[test]
@@ -97,9 +97,8 @@ pub fn restrict_media_hosts(html: &str, allowed_host: &str) -> String {
97 97 .attribute_filter(move |element, attribute, value| {
98 98 let is_media_src = matches!(
99 99 (element, attribute),
100 - ("img", "src" | "srcset")
100 + ("img" | "source", "src" | "srcset")
101 101 | ("video", "src" | "poster")
102 - | ("source", "src" | "srcset")
103 102 | ("audio", "src")
104 103 );
105 104 if is_media_src {
@@ -148,46 +148,55 @@ impl Renderer {
148 148 }
149 149 }
150 150
151 + #[must_use]
151 152 pub fn with_tables(mut self, enabled: bool) -> Self {
152 153 self.tables = enabled;
153 154 self
154 155 }
155 156
157 + #[must_use]
156 158 pub fn with_strikethrough(mut self, enabled: bool) -> Self {
157 159 self.strikethrough = enabled;
158 160 self
159 161 }
160 162
163 + #[must_use]
161 164 pub fn with_footnotes(mut self, enabled: bool) -> Self {
162 165 self.footnotes = enabled;
163 166 self
164 167 }
165 168
169 + #[must_use]
166 170 pub fn with_smart_punctuation(mut self, enabled: bool) -> Self {
167 171 self.smart_punctuation = enabled;
168 172 self
169 173 }
170 174
175 + #[must_use]
171 176 pub fn with_tasklists(mut self, enabled: bool) -> Self {
172 177 self.tasklists = enabled;
173 178 self
174 179 }
175 180
181 + #[must_use]
176 182 pub fn with_strip_images(mut self, enabled: bool) -> Self {
177 183 self.strip_images = enabled;
178 184 self
179 185 }
180 186
187 + #[must_use]
181 188 pub fn with_strip_raw_html(mut self, enabled: bool) -> Self {
182 189 self.strip_raw_html = enabled;
183 190 self
184 191 }
185 192
193 + #[must_use]
186 194 pub fn with_dangerous_scheme_filter(mut self, enabled: bool) -> Self {
187 195 self.dangerous_scheme_filter = enabled;
188 196 self
189 197 }
190 198
199 + #[must_use]
191 200 pub fn with_sanitize(mut self, preset: SanitizePreset) -> Self {
192 201 self.sanitize = preset;
193 202 self
@@ -205,6 +214,7 @@ impl Renderer {
205 214 /// content — docs, your own long-form — not for arbitrary UGC.
206 215 ///
207 216 /// [`extract_toc`]: crate::extract_toc
217 + #[must_use]
208 218 pub fn with_heading_ids(mut self, enabled: bool) -> Self {
209 219 self.heading_ids = enabled;
210 220 self
@@ -370,7 +380,7 @@ mod tests {
370 380 fn permissive_smart_punctuation() {
371 381 let r = Renderer::permissive();
372 382 let html = r.render("It's a \"test\"");
373 - assert!(html.contains('\u{201c}') || html.contains('\u{201d}') || html.contains("\""));
383 + assert!(html.contains('\u{201c}') || html.contains('\u{201d}') || html.contains('"'));
374 384 }
375 385
376 386 #[test]
@@ -423,13 +433,11 @@ mod tests {
423 433 .render("hello <u>raw</u> world");
424 434 assert!(
425 435 kept.contains("<u>"),
426 - "<u> should survive permissive: {}",
427 - kept
436 + "<u> should survive permissive: {kept}"
428 437 );
429 438 assert!(
430 439 !stripped.contains("<u>"),
431 - "<u> should be stripped: {}",
432 - stripped
440 + "<u> should be stripped: {stripped}"
433 441 );
434 442 }
435 443
@@ -26,7 +26,7 @@ pub(crate) fn permissive_builder() -> ammonia::Builder<'static> {
26 26 }
27 27
28 28 impl SanitizePreset {
29 - pub(crate) fn clean(&self, html: &str) -> String {
29 + pub(crate) fn clean(self, html: &str) -> String {
30 30 self.clean_with(html, false)
31 31 }
32 32
@@ -40,7 +40,7 @@ impl SanitizePreset {
40 40 /// about when that is safe.
41 41 ///
42 42 /// [`Renderer::with_heading_ids`]: crate::Renderer::with_heading_ids
43 - pub(crate) fn clean_with(&self, html: &str, allow_heading_ids: bool) -> String {
43 + pub(crate) fn clean_with(self, html: &str, allow_heading_ids: bool) -> String {
44 44 let mut builder = match self {
45 45 SanitizePreset::Permissive | SanitizePreset::Standard => permissive_builder(),
46 46 SanitizePreset::Strict => {
@@ -191,7 +191,7 @@ mod tests {
191 191 // SVG is a script-carrier (`<svg><script>` / animated `<set>`); ammonia's
192 192 // default allowlist excludes it. Pin that so a default change can't admit
193 193 // an SVG XSS vector into creator long-form content.
194 - let html = r#"<p>x</p><svg><script>alert(1)</script></svg>"#;
194 + let html = r"<p>x</p><svg><script>alert(1)</script></svg>";
195 195 let result = SanitizePreset::Permissive.clean(html);
196 196 assert!(!result.contains("<svg"), "svg must be stripped: {result}");
197 197 assert!(
@@ -1,5 +1,6 @@
1 1 use std::collections::HashMap;
2 2 use std::collections::hash_map::Entry;
3 + use std::fmt::Write as _;
3 4
4 5 use pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};
5 6
@@ -89,12 +90,13 @@ pub fn render_toc_html(entries: &[TocEntry]) -> String {
89 90 }
90 91 let mut html = String::from("<nav class=\"toc\"><ul>\n");
91 92 for entry in entries {
92 - html.push_str(&format!(
93 - "<li class=\"toc-h{}\"><a href=\"#{}\">{}</a></li>\n",
93 + let _ = writeln!(
94 + html,
95 + "<li class=\"toc-h{}\"><a href=\"#{}\">{}</a></li>",
94 96 entry.level,
95 97 html_escape(&entry.anchor),
96 98 html_escape(&entry.text),
97 - ));
99 + );
98 100 }
99 101 html.push_str("</ul></nav>");
100 102 html