tidy/
rustdoc_css_themes.rs1use std::path::Path;
5
6use crate::diagnostics::{CheckId, DiagCtx, RunningCheck};
7
8pub fn check(librustdoc_path: &Path, diag_ctx: DiagCtx) {
9 let mut check = diag_ctx.start_check(CheckId::new("rustdoc_css_themes").path(librustdoc_path));
10
11 let rustdoc_css = "html/static/css/rustdoc.css";
12 let noscript_css = "html/static/css/noscript.css";
13 let rustdoc_css_contents = std::fs::read_to_string(librustdoc_path.join(rustdoc_css))
14 .unwrap_or_else(|e| panic!("failed to read librustdoc/{rustdoc_css}: {e}"));
15 let noscript_css_contents = std::fs::read_to_string(librustdoc_path.join(noscript_css))
16 .unwrap_or_else(|e| panic!("failed to read librustdoc/{noscript_css}: {e}"));
17 compare_themes_from_files(
18 "light",
19 rustdoc_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())),
20 noscript_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())),
21 &mut check,
22 );
23 compare_themes_from_files(
24 "dark",
25 rustdoc_css_contents.lines().enumerate(),
26 noscript_css_contents.lines().enumerate(),
27 &mut check,
28 );
29}
30
31fn compare_themes_from_files<'a>(
32 name: &str,
33 mut rustdoc_css_lines: impl Iterator<Item = (usize, &'a str)>,
34 mut noscript_css_lines: impl Iterator<Item = (usize, &'a str)>,
35 check: &mut RunningCheck,
36) {
37 let begin_theme_pat = format!("/* Begin theme: {name}");
38 let mut found_theme = None;
39 let mut found_theme_noscript = None;
40 while let Some((rustdoc_css_line_number, rustdoc_css_line)) = rustdoc_css_lines.next() {
41 if !rustdoc_css_line.starts_with(&begin_theme_pat) {
42 continue;
43 }
44 if let Some(found_theme) = found_theme {
45 check.error(format!(
46 "rustdoc.css contains two {name} themes on lines {rustdoc_css_line_number} and {found_theme}",
47 ));
48 return;
49 }
50 found_theme = Some(rustdoc_css_line_number);
51 while let Some((noscript_css_line_number, noscript_css_line)) = noscript_css_lines.next() {
52 if !noscript_css_line.starts_with(&begin_theme_pat) {
53 continue;
54 }
55 if let Some(found_theme_noscript) = found_theme_noscript {
56 check.error(format!(
57 "noscript.css contains two {name} themes on lines {noscript_css_line_number} and {found_theme_noscript}",
58 ));
59 return;
60 }
61 found_theme_noscript = Some(noscript_css_line_number);
62 compare_themes(name, &mut rustdoc_css_lines, &mut noscript_css_lines, check);
63 }
64 }
65}
66
67fn compare_themes<'a>(
68 name: &str,
69 rustdoc_css_lines: impl Iterator<Item = (usize, &'a str)>,
70 noscript_css_lines: impl Iterator<Item = (usize, &'a str)>,
71 check: &mut RunningCheck,
72) {
73 let end_theme_pat = format!("/* End theme: {name}");
74 for (
75 (rustdoc_css_line_number, rustdoc_css_line),
76 (noscript_css_line_number, noscript_css_line),
77 ) in rustdoc_css_lines.zip(noscript_css_lines)
78 {
79 if noscript_css_line.starts_with(":root, :root:not([data-theme]) {")
80 && (rustdoc_css_line.starts_with(&format!(r#":root[data-theme="{name}"] {{"#))
81 || rustdoc_css_line.starts_with(&format!(
82 r#":root[data-theme="{name}"], :root:not([data-theme]) {{"#
83 )))
84 {
85 continue;
88 }
89 if noscript_css_line.starts_with(&end_theme_pat)
90 && rustdoc_css_line.starts_with(&end_theme_pat)
91 {
92 break;
93 }
94 if rustdoc_css_line != noscript_css_line {
95 check.error(format!(
96 r#"noscript.css:{noscript_css_line_number} and rustdoc.css:{rustdoc_css_line_number} contain copies of {name} theme that are not the same
97- {noscript_css_line}
98+ {rustdoc_css_line}"#,
99 ));
100 return;
101 }
102 }
103}