1use crate::{embedded_hljs as hljs, embedded_pico};
15
16pub const TASKS_CHUNK_ROUTE: &str = "/components/mbr-tasks.min.js";
22
23pub const REVIEW_CHUNK_ROUTE: &str = "/components/mbr-review.min.js";
30
31pub const SEARCH_EXTRAS_CHUNK_ROUTE: &str = "/components/mbr-search-extras.min.js";
38
39const JS: &str = "application/javascript";
40const CSS: &str = "text/css";
41
42pub const FAVICON_PNG: &[u8] = include_bytes!("../templates/favicon.png");
43pub const THEME_CSS: &[u8] = include_bytes!("../templates/theme.css");
44pub const USER_CSS: &[u8] = include_bytes!("../templates/user.css");
45
46pub const COMPONENTS_JS: &[u8] = include_bytes!("../templates/components-js/mbr-components.min.js");
48pub const EDITOR_JS: &[u8] = include_bytes!("../templates/components-js/mbr-editor.min.js");
50pub const GRAPH_JS: &[u8] = include_bytes!("../templates/components-js/mbr-graph.min.js");
53pub const GENEALOGY_JS: &[u8] = include_bytes!("../templates/components-js/mbr-genealogy.min.js");
56pub const TASKS_JS: &[u8] = include_bytes!("../templates/components-js/mbr-tasks.min.js");
59pub const REVIEW_JS: &[u8] = include_bytes!("../templates/components-js/mbr-review.min.js");
63pub const SEARCH_EXTRAS_JS: &[u8] =
67 include_bytes!("../templates/components-js/mbr-search-extras.min.js");
68pub const FLASHCARDS_JS: &[u8] = include_bytes!("../templates/components-js/mbr-flashcards.min.js");
72pub const FLASHCARDS_READING_JS: &[u8] =
76 include_bytes!("../templates/components-js/mbr-flashcards-reading.min.js");
77
78pub const MERMAID_JS: &[u8] = include_bytes!("../templates/mermaid.12.1.0.min.js");
79
80pub const REVEAL_JS: &[u8] = include_bytes!("../templates/reveal.6.0.2.js");
82pub const REVEAL_CSS: &[u8] = include_bytes!("../templates/reveal.6.0.2.css");
83pub const REVEAL_THEME_BLANK_CSS: &[u8] =
84 include_bytes!("../templates/reveal.theme.blank.5.2.1.css");
85pub const REVEAL_THEME_BLACK_CSS: &[u8] =
86 include_bytes!("../templates/reveal.theme.black.5.2.1.css");
87pub const REVEAL_THEME_WHITE_CSS: &[u8] =
88 include_bytes!("../templates/reveal.theme.white.5.2.1.css");
89pub const REVEAL_SLIDES_CSS: &[u8] = include_bytes!("../templates/reveal-slides.css");
90pub const REVEAL_NOTES_JS: &[u8] = include_bytes!("../templates/reveal.notes.6.0.2.js");
91
92pub const DEFAULT_FILES: &[(&str, &[u8], &str)] = &[
97 ("/favicon.png", FAVICON_PNG, "image/png"),
98 ("/theme.css", THEME_CSS, CSS),
99 ("/user.css", USER_CSS, CSS),
100 ("/pico.min.css", embedded_pico::PICO_DEFAULT, CSS),
101 ("/components/mbr-components.min.js", COMPONENTS_JS, JS),
102 ("/components/mbr-editor.min.js", EDITOR_JS, JS),
103 ("/components/mbr-graph.min.js", GRAPH_JS, JS),
104 ("/components/mbr-genealogy.min.js", GENEALOGY_JS, JS),
105 (TASKS_CHUNK_ROUTE, TASKS_JS, JS),
106 (REVIEW_CHUNK_ROUTE, REVIEW_JS, JS),
107 (SEARCH_EXTRAS_CHUNK_ROUTE, SEARCH_EXTRAS_JS, JS),
108 ("/components/mbr-flashcards.min.js", FLASHCARDS_JS, JS),
109 (
110 "/components/mbr-flashcards-reading.min.js",
111 FLASHCARDS_READING_JS,
112 JS,
113 ),
114 ("/hljs.dark.css", hljs::HLJS_DARK_CSS, CSS),
115 ("/hljs.atom-one-dark.css", hljs::HLJS_ATOM_ONE_DARK_CSS, CSS),
116 ("/hljs.js", hljs::HLJS_JS, JS),
117 ("/hljs.lang.css.js", hljs::HLJS_LANG_CSS, JS),
118 ("/hljs.lang.javascript.js", hljs::HLJS_LANG_JAVASCRIPT, JS),
119 ("/hljs.lang.typescript.js", hljs::HLJS_LANG_TYPESCRIPT, JS),
120 ("/hljs.lang.rust.js", hljs::HLJS_LANG_RUST, JS),
121 ("/hljs.lang.python.js", hljs::HLJS_LANG_PYTHON, JS),
122 ("/hljs.lang.bash.js", hljs::HLJS_LANG_BASH, JS),
123 ("/hljs.lang.java.js", hljs::HLJS_LANG_JAVA, JS),
124 ("/hljs.lang.scala.js", hljs::HLJS_LANG_SCALA, JS),
125 ("/hljs.lang.go.js", hljs::HLJS_LANG_GO, JS),
126 ("/hljs.lang.ruby.js", hljs::HLJS_LANG_RUBY, JS),
127 ("/hljs.lang.nix.js", hljs::HLJS_LANG_NIX, JS),
128 ("/hljs.lang.json.js", hljs::HLJS_LANG_JSON, JS),
129 ("/hljs.lang.yaml.js", hljs::HLJS_LANG_YAML, JS),
130 ("/hljs.lang.xml.js", hljs::HLJS_LANG_XML, JS),
131 ("/hljs.lang.sql.js", hljs::HLJS_LANG_SQL, JS),
132 ("/hljs.lang.dockerfile.js", hljs::HLJS_LANG_DOCKERFILE, JS),
133 ("/hljs.lang.markdown.js", hljs::HLJS_LANG_MARKDOWN, JS),
134 ("/mermaid.min.js", MERMAID_JS, JS),
135 ("/reveal.js", REVEAL_JS, JS),
136 ("/reveal.css", REVEAL_CSS, CSS),
137 ("/reveal-theme-blank.css", REVEAL_THEME_BLANK_CSS, CSS),
138 ("/reveal-theme-black.css", REVEAL_THEME_BLACK_CSS, CSS),
139 ("/reveal-theme-white.css", REVEAL_THEME_WHITE_CSS, CSS),
140 ("/reveal-slides.css", REVEAL_SLIDES_CSS, CSS),
141 ("/reveal-notes.js", REVEAL_NOTES_JS, JS),
142];
143
144#[must_use]
148pub fn default_file(route: &str) -> Option<(&'static [u8], &'static str)> {
149 DEFAULT_FILES
150 .iter()
151 .find(|(name, _, _)| *name == route)
152 .map(|(_, bytes, mime)| (*bytes, *mime))
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158 use std::collections::HashSet;
159
160 #[test]
161 fn routes_are_unique_and_rooted() {
162 let mut seen = HashSet::new();
163 for (route, _, _) in DEFAULT_FILES {
164 assert!(route.starts_with('/'), "route {route} must start with /");
165 assert!(seen.insert(*route), "duplicate route {route}");
166 }
167 }
168
169 #[test]
170 fn default_file_finds_every_table_entry() {
171 for (route, bytes, mime) in DEFAULT_FILES {
172 assert_eq!(default_file(route), Some((*bytes, *mime)));
173 }
174 assert_eq!(default_file("/nope.js"), None);
175 }
176
177 #[test]
178 fn chunk_routes_are_in_the_table() {
179 for route in [
180 TASKS_CHUNK_ROUTE,
181 REVIEW_CHUNK_ROUTE,
182 SEARCH_EXTRAS_CHUNK_ROUTE,
183 ] {
184 assert!(default_file(route).is_some(), "{route} missing");
185 }
186 }
187
188 #[test]
189 fn quicklook_assets_match_their_routes() {
190 assert_eq!(default_file("/theme.css").map(|(b, _)| b), Some(THEME_CSS));
191 assert_eq!(
192 default_file("/mermaid.min.js").map(|(b, _)| b),
193 Some(MERMAID_JS)
194 );
195 }
196}