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