forc_doc/render/
link.rs

1//! Handles creation of links for modules.
2use crate::{
3    doc::module::ModuleInfo,
4    render::{BlockTitle, DocStyle, Renderable},
5    RenderPlan,
6};
7use anyhow::Result;
8use horrorshow::{box_html, Raw, RenderBox, Template};
9use std::collections::BTreeMap;
10
11/// Used for creating links between docs.
12#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
13pub struct DocLink {
14    pub name: String,
15    pub module_info: ModuleInfo,
16    pub html_filename: String,
17    pub preview_opt: Option<String>,
18}
19
20#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
21pub struct DocLinks {
22    pub style: DocStyle,
23    /// The title and link info for each doc item.
24    pub links: BTreeMap<BlockTitle, Vec<DocLink>>,
25}
26
27impl Renderable for DocLinks {
28    fn render(self, _render_plan: RenderPlan) -> Result<Box<dyn RenderBox>> {
29        let mut links_vec = Vec::new();
30        // sort the doc links alphabetically
31        // for the AllDoc page, sort based on the module prefix and name
32        match self.style {
33            DocStyle::AllDoc(_) => {
34                for (block_title, mut doc_link) in self.links {
35                    doc_link.sort_by(|a, b| {
36                        let first = a
37                            .module_info
38                            .to_path_literal_string(&a.name, a.module_info.project_name());
39                        let second = b
40                            .module_info
41                            .to_path_literal_string(&b.name, b.module_info.project_name());
42                        first.cmp(&second)
43                    });
44                    links_vec.push((block_title, doc_link));
45                }
46            }
47            _ => {
48                for (block_title, mut doc_link) in self.links {
49                    doc_link.sort();
50                    links_vec.push((block_title.clone(), doc_link.to_vec()));
51                }
52            }
53        }
54        let doc_links = match self.style {
55            DocStyle::AllDoc(_) => box_html! {
56                @ for (title, list_items) in links_vec {
57                    @ if !list_items.is_empty() {
58                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
59                        div(class="item-table") {
60                            @ for item in list_items {
61                                div(class="item-row") {
62                                    div(class=format!("item-left {}-item", title.item_title_str())) {
63                                        a(
64                                            class=title.class_title_str(),
65                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.project_name())
66                                        ) {
67                                            : item.module_info.to_path_literal_string(
68                                                &item.name,
69                                                item.module_info.project_name()
70                                            );
71                                        }
72                                    }
73                                    @ if item.preview_opt.is_some() {
74                                        div(class="item-right docblock-short") {
75                                            : Raw(item.preview_opt.clone().unwrap());
76                                        }
77                                    }
78                                }
79                            }
80                        }
81                    }
82                }
83            }
84            .into_string()
85            .unwrap(),
86            DocStyle::ProjectIndex(_) => box_html! {
87                @ for (title, list_items) in links_vec {
88                    @ if !list_items.is_empty() {
89                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
90                        div(class="item-table") {
91                            @ for item in list_items {
92                                div(class="item-row") {
93                                    div(class=format!("item-left {}-item", title.item_title_str())) {
94                                        a(
95                                            class=title.class_title_str(),
96                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.project_name())
97                                        ) {
98                                            @ if title == BlockTitle::Modules {
99                                                : item.name.clone();
100                                            } else {
101                                                : item.module_info.to_path_literal_string(
102                                                    &item.name,
103                                                    item.module_info.project_name()
104                                                );
105                                            }
106                                        }
107                                    }
108                                    @ if item.preview_opt.is_some() {
109                                        div(class="item-right docblock-short") {
110                                            : Raw(item.preview_opt.clone().unwrap());
111                                        }
112                                    }
113                                }
114                            }
115                        }
116                    }
117                }
118            }
119            .into_string()
120            .unwrap(),
121            _ => box_html! {
122                @ for (title, list_items) in links_vec {
123                    @ if !list_items.is_empty() {
124                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
125                        div(class="item-table") {
126                            @ for item in list_items {
127                                div(class="item-row") {
128                                    div(class=format!("item-left {}-item", title.item_title_str())) {
129                                        a(
130                                            class=title.class_title_str(),
131                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.location())
132                                        ) {
133                                            : item.module_info.to_path_literal_string(
134                                                &item.name,
135                                                item.module_info.location()
136                                            );
137                                        }
138                                    }
139                                    @ if item.preview_opt.is_some() {
140                                        div(class="item-right docblock-short") {
141                                            : Raw(item.preview_opt.clone().unwrap());
142                                        }
143                                    }
144                                }
145                            }
146                        }
147                    }
148                }
149            }
150            .into_string()
151            .unwrap(),
152        };
153        Ok(box_html! {
154            : Raw(doc_links);
155        })
156    }
157}