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