1 use crate::html::markdown::{ErrorCodes, HeadingOffset, IdMap, Markdown, Playground};
2 use crate::rustc_span::edition::Edition;
3 use std::fs;
4 use std::path::Path;
5 use std::str;
6 
7 use serde::Serialize;
8 
9 #[derive(Clone, Debug, Serialize)]
10 crate struct ExternalHtml {
11     /// Content that will be included inline in the `<head>` section of a
12     /// rendered Markdown file or generated documentation
13     crate in_header: String,
14     /// Content that will be included inline between `<body>` and the content of
15     /// a rendered Markdown file or generated documentation
16     crate before_content: String,
17     /// Content that will be included inline between the content and `</body>` of
18     /// a rendered Markdown file or generated documentation
19     crate after_content: String,
20 }
21 
22 impl ExternalHtml {
load( in_header: &[String], before_content: &[String], after_content: &[String], md_before_content: &[String], md_after_content: &[String], nightly_build: bool, diag: &rustc_errors::Handler, id_map: &mut IdMap, edition: Edition, playground: &Option<Playground>, ) -> Option<ExternalHtml>23     crate fn load(
24         in_header: &[String],
25         before_content: &[String],
26         after_content: &[String],
27         md_before_content: &[String],
28         md_after_content: &[String],
29         nightly_build: bool,
30         diag: &rustc_errors::Handler,
31         id_map: &mut IdMap,
32         edition: Edition,
33         playground: &Option<Playground>,
34     ) -> Option<ExternalHtml> {
35         let codes = ErrorCodes::from(nightly_build);
36         let ih = load_external_files(in_header, diag)?;
37         let bc = load_external_files(before_content, diag)?;
38         let m_bc = load_external_files(md_before_content, diag)?;
39         let bc = format!(
40             "{}{}",
41             bc,
42             Markdown {
43                 content: &m_bc,
44                 links: &[],
45                 ids: id_map,
46                 error_codes: codes,
47                 edition,
48                 playground,
49                 heading_offset: HeadingOffset::H2,
50             }
51             .into_string()
52         );
53         let ac = load_external_files(after_content, diag)?;
54         let m_ac = load_external_files(md_after_content, diag)?;
55         let ac = format!(
56             "{}{}",
57             ac,
58             Markdown {
59                 content: &m_ac,
60                 links: &[],
61                 ids: id_map,
62                 error_codes: codes,
63                 edition,
64                 playground,
65                 heading_offset: HeadingOffset::H2,
66             }
67             .into_string()
68         );
69         Some(ExternalHtml { in_header: ih, before_content: bc, after_content: ac })
70     }
71 }
72 
73 crate enum LoadStringError {
74     ReadFail,
75     BadUtf8,
76 }
77 
load_string<P: AsRef<Path>>( file_path: P, diag: &rustc_errors::Handler, ) -> Result<String, LoadStringError>78 crate fn load_string<P: AsRef<Path>>(
79     file_path: P,
80     diag: &rustc_errors::Handler,
81 ) -> Result<String, LoadStringError> {
82     let file_path = file_path.as_ref();
83     let contents = match fs::read(file_path) {
84         Ok(bytes) => bytes,
85         Err(e) => {
86             diag.struct_err(&format!("error reading `{}`: {}", file_path.display(), e)).emit();
87             return Err(LoadStringError::ReadFail);
88         }
89     };
90     match str::from_utf8(&contents) {
91         Ok(s) => Ok(s.to_string()),
92         Err(_) => {
93             diag.struct_err(&format!("error reading `{}`: not UTF-8", file_path.display())).emit();
94             Err(LoadStringError::BadUtf8)
95         }
96     }
97 }
98 
load_external_files(names: &[String], diag: &rustc_errors::Handler) -> Option<String>99 fn load_external_files(names: &[String], diag: &rustc_errors::Handler) -> Option<String> {
100     let mut out = String::new();
101     for name in names {
102         let s = match load_string(name, diag) {
103             Ok(s) => s,
104             Err(_) => return None,
105         };
106         out.push_str(&s);
107         out.push('\n');
108     }
109     Some(out)
110 }
111