Skip to content

Commit 3409ada

Browse files
Move fontawesome icons check at compile-time
1 parent d5a3784 commit 3409ada

26 files changed

+206
-136
lines changed

src/web/build_details.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use crate::{
55
error::{AxumNope, AxumResult},
66
extractors::{DbConnection, Path},
77
file::File,
8-
filters, MetaData,
8+
filters,
9+
page::templates::traits::*,
10+
MetaData,
911
},
1012
AsyncStorage, Config,
1113
};

src/web/builds.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use crate::{
1111
web::{
1212
error::AxumResult,
1313
extractors::{DbConnection, Path},
14-
filters, match_version, MetaData, ReqVersion,
14+
filters, match_version,
15+
page::templates::traits::*,
16+
MetaData, ReqVersion,
1517
},
1618
BuildQueue, Config,
1719
};

src/web/crate_details.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
encode_url_path,
1111
error::{AxumNope, AxumResult},
1212
extractors::{DbConnection, Path},
13-
page::templates::filters,
13+
page::templates::{filters, traits::*},
1414
rustdoc::RustdocHtmlParams,
1515
MatchedRelease, ReqVersion,
1616
},

src/web/features.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use crate::{
77
extractors::{DbConnection, Path},
88
filters,
99
headers::CanonicalUrl,
10-
match_version, MetaData, ReqVersion,
10+
match_version,
11+
page::templates::traits::*,
12+
MetaData, ReqVersion,
1113
},
1214
};
1315
use anyhow::anyhow;

src/web/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub mod page;
66
use crate::db::types::BuildStatus;
77
use crate::utils::get_correct_docsrs_style_file;
88
use crate::utils::report_error;
9-
use crate::web::page::templates::filters;
9+
use crate::web::page::templates::{filters, traits::*};
1010
use anyhow::{anyhow, bail, Context as _, Result};
1111
use axum_extra::middleware::option_layer;
1212
use rinja::Template;

src/web/page/mod.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@ pub(crate) mod web_page;
33

44
pub(crate) use templates::TemplateData;
55

6-
use serde::Serialize;
6+
use serde::ser::{Serialize, SerializeStruct, Serializer};
77

8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize)]
8+
use templates::traits::*;
9+
10+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
911
pub(crate) struct GlobalAlert {
1012
pub(crate) url: &'static str,
1113
pub(crate) text: &'static str,
1214
pub(crate) css_class: &'static str,
13-
pub(crate) fa_icon: &'static str,
15+
pub(crate) fa_icon: templates::filters::TriangleExclamation,
16+
}
17+
18+
impl Serialize for GlobalAlert {
19+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
20+
where
21+
S: Serializer,
22+
{
23+
let mut s = serializer.serialize_struct("GlobalAlert", 4)?;
24+
s.serialize_field("url", &self.url)?;
25+
s.serialize_field("text", &self.text)?;
26+
s.serialize_field("css_class", &self.css_class)?;
27+
s.serialize_field("fa_icon", &self.fa_icon.as_str())?;
28+
s.end()
29+
}
1430
}
1531

1632
#[cfg(test)]
@@ -24,14 +40,14 @@ mod tera_tests {
2440
url: "http://www.hasthelargehadroncolliderdestroyedtheworldyet.com/",
2541
text: "THE WORLD WILL SOON END",
2642
css_class: "THE END IS NEAR",
27-
fa_icon: "https://gph.is/1uOvmqR",
43+
fa_icon: templates::filters::TriangleExclamation,
2844
};
2945

3046
let correct_json = json!({
3147
"url": "http://www.hasthelargehadroncolliderdestroyedtheworldyet.com/",
3248
"text": "THE WORLD WILL SOON END",
3349
"css_class": "THE END IS NEAR",
34-
"fa_icon": "https://gph.is/1uOvmqR"
50+
"fa_icon": "triangle-exclamation"
3551
});
3652

3753
assert_eq!(correct_json, serde_json::to_value(alert).unwrap());

src/web/page/templates.rs

Lines changed: 98 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::error::Result;
22
use crate::web::rustdoc::RustdocPage;
3-
use anyhow::{anyhow, Context};
3+
use anyhow::Context;
44
use rinja::Template;
5-
use std::{fmt, sync::Arc};
5+
use std::sync::Arc;
66
use tracing::trace;
77

88
#[derive(Template)]
@@ -88,7 +88,6 @@ impl TemplateData {
8888
}
8989

9090
pub mod filters {
91-
use super::IconType;
9291
use chrono::{DateTime, Utc};
9392
use rinja::filters::Safe;
9493
use std::borrow::Cow;
@@ -201,18 +200,6 @@ pub mod filters {
201200
Ok(unindented)
202201
}
203202

204-
pub fn fas(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
205-
IconType::Strong.render(value, fw, spin, extra).map(Safe)
206-
}
207-
208-
pub fn far(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
209-
IconType::Regular.render(value, fw, spin, extra).map(Safe)
210-
}
211-
212-
pub fn fab(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
213-
IconType::Brand.render(value, fw, spin, extra).map(Safe)
214-
}
215-
216203
pub fn highlight(code: impl std::fmt::Display, lang: &str) -> rinja::Result<Safe<String>> {
217204
let highlighted_code = crate::web::highlight::with_lang(Some(lang), &code.to_string());
218205
Ok(Safe(format!(
@@ -239,44 +226,107 @@ pub mod filters {
239226
serde_json::to_string(value).expect("`encode_json` failed"),
240227
))
241228
}
242-
}
243229

244-
enum IconType {
245-
Strong,
246-
Regular,
247-
Brand,
248-
}
230+
macro_rules! icons {
231+
($($name:ident => $class:literal: $($trait_:ident $(+)?)+ , )+) => {
232+
$(
233+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
234+
pub struct $name;
235+
236+
$(
237+
impl super::traits::$trait_ for $name {}
238+
)+
249239

250-
impl fmt::Display for IconType {
251-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252-
let icon = match self {
253-
Self::Strong => "solid",
254-
Self::Regular => "regular",
255-
Self::Brand => "brands",
240+
impl super::traits::IconStr for $name {
241+
fn as_str(&self) -> &'static str {
242+
$class
243+
}
244+
}
245+
)+
256246
};
247+
}
257248

258-
f.write_str(icon)
249+
icons! {
250+
House => "house": Solid,
251+
CodeBranch => "code-branch": Solid,
252+
Star => "star": Solid + Regular,
253+
File => "file": Regular,
254+
FileLines => "file-lines": Solid + Regular,
255+
CircleExclamation => "circle-exclamation": Solid,
256+
CircleInfo => "circle-info": Solid,
257+
Cube => "cube": Solid,
258+
Cubes => "cubes": Solid,
259+
Gear => "gear": Solid,
260+
Gears => "gears": Solid,
261+
Check => "check": Solid,
262+
TriangleExclamation => "triangle-exclamation": Solid + Regular,
263+
X => "x": Solid,
264+
ChevronLeft => "chevron-feft": Solid,
265+
ChevronRight => "chevron-right": Solid,
266+
Lock => "lock": Solid,
267+
Table => "table": Solid,
268+
Road => "road": Solid,
269+
Download => "download": Solid,
270+
Trash => "trash": Solid,
271+
ArrowLeft => "arrow-left": Solid,
272+
ArrowRight => "arrow-right": Solid,
273+
Leaf => "leaf": Solid,
274+
ChartLine => "chart-line": Solid,
275+
List => "list": Solid,
276+
User => "user": Solid,
277+
SquareRSS => "square-rss": Solid,
278+
MagnifyingGlass => "magnifying-glass": Solid,
279+
Flag => "flag": Solid,
280+
Book => "book": Solid,
281+
Link => "link": Solid,
282+
ScaleUnbalancedFlip => "scale-unbalanced-flip": Solid,
283+
FolderOpen => "folder-open": Solid + Regular,
284+
Spinner => "spinner": Solid,
285+
FontIcons => "fonticons": Brands, // It's not a typo!
286+
Rust => "rust": Brands,
287+
Markdown => "markdown": Brands,
288+
GitAlt => "git-alt": Brands,
259289
}
260290
}
261291

262-
impl IconType {
263-
fn render(self, icon_name: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<String> {
264-
let type_ = match self {
265-
IconType::Strong => font_awesome_as_a_crate::Type::Solid,
266-
IconType::Regular => font_awesome_as_a_crate::Type::Regular,
267-
IconType::Brand => font_awesome_as_a_crate::Type::Brands,
268-
};
292+
pub mod traits {
293+
pub trait IconStr {
294+
fn as_str(&self) -> &'static str;
295+
}
269296

270-
let icon_file_string = font_awesome_as_a_crate::svg(type_, icon_name).map_err(|err| {
271-
rinja::Error::Custom(
272-
anyhow!(err)
273-
.context(format!(
274-
"error trying to render icon with name \"{}\" and type \"{}\"",
275-
icon_name, type_,
276-
))
277-
.into(),
278-
)
279-
})?;
297+
macro_rules! icon_type {
298+
($($trait_:ident => $method:ident,)+) => {
299+
$(
300+
pub trait $trait_: IconStr {
301+
fn $method(&self, fw: bool, spin: bool, extra: &str) -> rinja::filters::Safe<String> {
302+
render_icon(IconStr::as_str(self), font_awesome_as_a_crate::Type::$trait_, fw, spin, extra)
303+
}
304+
}
305+
)+
306+
}
307+
}
308+
309+
icon_type!(
310+
Solid => render_solid,
311+
Regular => render_regular,
312+
Brands => render_brands,
313+
);
314+
315+
fn render_icon(
316+
icon_name: &str,
317+
type_: font_awesome_as_a_crate::Type,
318+
fw: bool,
319+
spin: bool,
320+
extra: &str,
321+
) -> rinja::filters::Safe<String> {
322+
let Ok(icon_file_string) = font_awesome_as_a_crate::svg(type_, icon_name) else {
323+
log::error!(
324+
"error trying to render icon with name \"{}\" and type \"{}\"",
325+
icon_name,
326+
type_,
327+
);
328+
return rinja::filters::Safe(String::new());
329+
};
280330

281331
let mut classes = vec!["fa-svg"];
282332
if fw {
@@ -288,12 +338,10 @@ impl IconType {
288338
if !extra.is_empty() {
289339
classes.push(extra);
290340
}
291-
let icon = format!(
341+
rinja::filters::Safe(format!(
292342
"\
293-
<span class=\"{class}\" aria-hidden=\"true\">{icon_file_string}</span>",
343+
<span class=\"{class}\" aria-hidden=\"true\">{icon_file_string}</span>",
294344
class = classes.join(" "),
295-
);
296-
297-
Ok(icon)
345+
))
298346
}
299347
}

src/web/releases.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
error::{AxumNope, AxumResult},
1212
extractors::{DbConnection, Path},
1313
match_version,
14-
page::templates::filters,
14+
page::templates::{filters, traits::*},
1515
ReqVersion,
1616
},
1717
BuildQueue, Config, InstanceMetrics,

src/web/rustdoc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::{
1414
extractors::{DbConnection, Path},
1515
file::File,
1616
match_version,
17-
page::templates::filters,
17+
page::templates::{filters, traits::*},
1818
page::TemplateData,
1919
MetaData, ReqVersion,
2020
},

src/web/sitemap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
web::{
77
error::{AxumNope, AxumResult},
88
extractors::{DbConnection, Path},
9-
page::templates::filters,
9+
page::templates::{filters, traits::*},
1010
AxumErrorPage,
1111
},
1212
Config,

0 commit comments

Comments
 (0)