]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/html/layout.rs
Rollup merge of #93394 - m-ou-se:fix-93378, r=estebank
[rust.git] / src / librustdoc / html / layout.rs
1 use std::path::PathBuf;
2
3 use rustc_data_structures::fx::FxHashMap;
4
5 use crate::error::Error;
6 use crate::externalfiles::ExternalHtml;
7 use crate::html::format::{Buffer, Print};
8 use crate::html::render::{ensure_trailing_slash, StylePath};
9
10 use askama::Template;
11
12 #[derive(Clone)]
13 crate struct Layout {
14     crate logo: String,
15     crate favicon: String,
16     crate external_html: ExternalHtml,
17     crate default_settings: FxHashMap<String, String>,
18     crate krate: String,
19     /// The given user css file which allow to customize the generated
20     /// documentation theme.
21     crate css_file_extension: Option<PathBuf>,
22     /// If true, then scrape-examples.js will be included in the output HTML file
23     crate scrape_examples_extension: bool,
24 }
25
26 crate struct Page<'a> {
27     crate title: &'a str,
28     crate css_class: &'a str,
29     crate root_path: &'a str,
30     crate static_root_path: Option<&'a str>,
31     crate description: &'a str,
32     crate keywords: &'a str,
33     crate resource_suffix: &'a str,
34     crate extra_scripts: &'a [&'a str],
35     crate static_extra_scripts: &'a [&'a str],
36 }
37
38 impl<'a> Page<'a> {
39     crate fn get_static_root_path(&self) -> &str {
40         self.static_root_path.unwrap_or(self.root_path)
41     }
42 }
43
44 #[derive(Template)]
45 #[template(path = "page.html")]
46 struct PageLayout<'a> {
47     static_root_path: &'a str,
48     page: &'a Page<'a>,
49     layout: &'a Layout,
50     themes: Vec<String>,
51     sidebar: String,
52     content: String,
53     krate_with_trailing_slash: String,
54     crate rustdoc_version: &'a str,
55 }
56
57 crate fn render<T: Print, S: Print>(
58     layout: &Layout,
59     page: &Page<'_>,
60     sidebar: S,
61     t: T,
62     style_files: &[StylePath],
63 ) -> String {
64     let static_root_path = page.get_static_root_path();
65     let krate_with_trailing_slash = ensure_trailing_slash(&layout.krate).to_string();
66     let mut themes: Vec<String> = style_files
67         .iter()
68         .map(StylePath::basename)
69         .collect::<Result<_, Error>>()
70         .unwrap_or_default();
71     themes.sort();
72     let rustdoc_version = rustc_interface::util::version_str().unwrap_or("unknown version");
73     let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
74     let sidebar = Buffer::html().to_display(sidebar);
75     PageLayout {
76         static_root_path,
77         page,
78         layout,
79         themes,
80         sidebar,
81         content,
82         krate_with_trailing_slash,
83         rustdoc_version,
84     }
85     .render()
86     .unwrap()
87 }
88
89 crate fn redirect(url: &str) -> String {
90     // <script> triggers a redirect before refresh, so this is fine.
91     format!(
92         r##"<!DOCTYPE html>
93 <html lang="en">
94 <head>
95     <meta http-equiv="refresh" content="0;URL={url}">
96     <title>Redirection</title>
97 </head>
98 <body>
99     <p>Redirecting to <a href="{url}">{url}</a>...</p>
100     <script>location.replace("{url}" + location.search + location.hash);</script>
101 </body>
102 </html>"##,
103         url = url,
104     )
105 }