1use camino::Utf8Path;
2use handlebars::handlebars_helper;
3use html_escape::encode_safe;
4use rust_embed::Embed;
5use serde::Serialize;
6
7#[derive(Embed)]
8#[folder = "templates"]
9struct Assets;
10
11handlebars_helper!(index: |events: array, i: usize| {
12 events[i].clone()
13});
14
15handlebars_helper!(is_type: |actual: str, expected: str| {
16 actual == expected
17});
18
19handlebars_helper!(source_snippet: |file: str, line: usize, column: usize| {
20 file_line_col(file, line, column)
21});
22
23pub(crate) fn render(name: &str, data: &impl Serialize) -> anyhow::Result<String> {
24 let mut handlers = handlebars::Handlebars::new();
25 handlers.register_embed_templates_with_extension::<Assets>(".hbs")?;
26 handlers.register_helper("index", Box::new(index));
27 handlers.register_helper("is_type", Box::new(is_type));
28 handlers.register_helper("source_snippet", Box::new(source_snippet));
29 Ok(handlers.render(name, data)?)
30}
31
32fn file_line_col(file: &str, line: usize, column: usize) -> String {
33 let path = Utf8Path::new(file);
34 let file_name = path.file_name().unwrap_or("rust");
35 format!(
36 "<a href='{href}'><img
37 alt='badge {file} {line} {column}'
38 src='https://img.shields.io/badge/source-{file}:{line}:{column}-orange'
39 /></a>",
40 href = file_line_col_href(file, line, column),
41 file = encode_safe(file_name).replace("-", "%2D"),
42 )
43}
44
45fn file_line_col_href(file: &str, line: usize, column: usize) -> String {
46 format!("/source/{file}?line={line}&column={column}")
47}