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