1use 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#[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 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 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}