1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! Handles creation of links for modules.
use crate::{
    doc::module::ModuleInfo,
    render::{BlockTitle, DocStyle, Renderable},
    RenderPlan,
};
use anyhow::Result;
use horrorshow::{box_html, Raw, RenderBox, Template};
use std::collections::BTreeMap;

/// Used for creating links between docs.
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct DocLink {
    pub name: String,
    pub module_info: ModuleInfo,
    pub html_filename: String,
    pub preview_opt: Option<String>,
}
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]
pub struct DocLinks {
    pub style: DocStyle,
    /// The title and link info for each doc item.
    pub links: BTreeMap<BlockTitle, Vec<DocLink>>,
}
impl Renderable for DocLinks {
    fn render(self, _render_plan: RenderPlan) -> Result<Box<dyn RenderBox>> {
        let mut links_vec = Vec::new();
        // sort the doc links alphabetically
        // for the AllDoc page, sort based on the module prefix and name
        match self.style {
            DocStyle::AllDoc(_) => {
                for (block_title, mut doc_link) in self.links {
                    doc_link.sort_by(|a, b| {
                        let first = a
                            .module_info
                            .to_path_literal_string(&a.name, a.module_info.project_name());
                        let second = b
                            .module_info
                            .to_path_literal_string(&b.name, b.module_info.project_name());
                        first.cmp(&second)
                    });
                    links_vec.push((block_title, doc_link));
                }
            }
            _ => {
                for (block_title, mut doc_link) in self.links {
                    doc_link.sort();
                    links_vec.push((block_title.clone(), doc_link.to_vec()));
                }
            }
        }
        let doc_links = match self.style {
            DocStyle::AllDoc(_) => box_html! {
                @ for (title, list_items) in links_vec {
                    @ if !list_items.is_empty() {
                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
                        div(class="item-table") {
                            @ for item in list_items {
                                div(class="item-row") {
                                    div(class=format!("item-left {}-item", title.item_title_str())) {
                                        a(
                                            class=title.class_title_str(),
                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.project_name())
                                        ) {
                                            : item.module_info.to_path_literal_string(
                                                &item.name,
                                                item.module_info.project_name()
                                            );
                                        }
                                    }
                                    @ if item.preview_opt.is_some() {
                                        div(class="item-right docblock-short") {
                                            : Raw(item.preview_opt.clone().unwrap());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            .into_string()
            .unwrap(),
            DocStyle::ProjectIndex(_) => box_html! {
                @ for (title, list_items) in links_vec {
                    @ if !list_items.is_empty() {
                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
                        div(class="item-table") {
                            @ for item in list_items {
                                div(class="item-row") {
                                    div(class=format!("item-left {}-item", title.item_title_str())) {
                                        a(
                                            class=title.class_title_str(),
                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.project_name())
                                        ) {
                                            @ if title == BlockTitle::Modules {
                                                : item.name.clone();
                                            } else {
                                                : item.module_info.to_path_literal_string(
                                                    &item.name,
                                                    item.module_info.project_name()
                                                );
                                            }
                                        }
                                    }
                                    @ if item.preview_opt.is_some() {
                                        div(class="item-right docblock-short") {
                                            : Raw(item.preview_opt.clone().unwrap());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            .into_string()
            .unwrap(),
            _ => box_html! {
                @ for (title, list_items) in links_vec {
                    @ if !list_items.is_empty() {
                        h2(id=format!("{}", title.html_title_string())) { : title.as_str(); }
                        div(class="item-table") {
                            @ for item in list_items {
                                div(class="item-row") {
                                    div(class=format!("item-left {}-item", title.item_title_str())) {
                                        a(
                                            class=title.class_title_str(),
                                            href=item.module_info.file_path_at_location(&item.html_filename, item.module_info.location())
                                        ) {
                                            : item.module_info.to_path_literal_string(
                                                &item.name,
                                                item.module_info.location()
                                            );
                                        }
                                    }
                                    @ if item.preview_opt.is_some() {
                                        div(class="item-right docblock-short") {
                                            : Raw(item.preview_opt.clone().unwrap());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            .into_string()
            .unwrap(),
        };
        Ok(box_html! {
            : Raw(doc_links);
        })
    }
}