Skip to content

Commit

Permalink
move fontawesome icons check at compile-time
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez committed Sep 27, 2024
1 parent 7cb5bb0 commit 50d6035
Show file tree
Hide file tree
Showing 18 changed files with 138 additions and 139 deletions.
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub use self::registry_api::RegistryApi;
pub use self::storage::{AsyncStorage, Storage};
pub use self::web::{start_background_metrics_webserver, start_web_server};

pub(crate) use font_awesome_as_a_crate as f_a;

mod build_queue;
pub mod cdn;
mod config;
Expand Down
25 changes: 20 additions & 5 deletions src/web/page/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,29 @@ pub(crate) mod web_page;

pub(crate) use templates::TemplateData;

use serde::Serialize;
use crate::f_a::IconStr;
use serde::ser::{Serialize, SerializeStruct, Serializer};

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub(crate) struct GlobalAlert {
pub(crate) url: &'static str,
pub(crate) text: &'static str,
pub(crate) css_class: &'static str,
pub(crate) fa_icon: &'static str,
pub(crate) fa_icon: crate::f_a::icons::IconTriangleExclamation,
}

impl Serialize for GlobalAlert {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("GlobalAlert", 4)?;
s.serialize_field("url", &self.url)?;
s.serialize_field("text", &self.text)?;
s.serialize_field("css_class", &self.css_class)?;
s.serialize_field("fa_icon", &self.fa_icon.icon_name())?;
s.end()
}
}

#[cfg(test)]
Expand All @@ -24,14 +39,14 @@ mod tera_tests {
url: "http://www.hasthelargehadroncolliderdestroyedtheworldyet.com/",
text: "THE WORLD WILL SOON END",
css_class: "THE END IS NEAR",
fa_icon: "https://gph.is/1uOvmqR",
fa_icon: crate::f_a::icons::IconTriangleExclamation,
};

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

assert_eq!(correct_json, serde_json::to_value(alert).unwrap());
Expand Down
106 changes: 44 additions & 62 deletions src/web/page/templates.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::error::Result;
use crate::web::rustdoc::RustdocPage;
use anyhow::{anyhow, Context};
use anyhow::Context;
use rinja::Template;
use std::{fmt, sync::Arc};
use std::sync::Arc;
use tracing::trace;

#[derive(Template)]
Expand Down Expand Up @@ -88,7 +88,6 @@ impl TemplateData {
}

pub mod filters {
use super::IconType;
use chrono::{DateTime, Utc};
use rinja::filters::Safe;
use std::borrow::Cow;
Expand Down Expand Up @@ -201,16 +200,31 @@ pub mod filters {
Ok(unindented)
}

pub fn fas(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
IconType::Strong.render(value, fw, spin, extra).map(Safe)
pub fn fas<T: font_awesome_as_a_crate::Solid>(
value: T,
fw: bool,
spin: bool,
extra: &str,
) -> rinja::Result<Safe<String>> {
super::render_icon(value.icon_str(), fw, spin, extra)
}

pub fn far(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
IconType::Regular.render(value, fw, spin, extra).map(Safe)
pub fn far<T: font_awesome_as_a_crate::Regular>(
value: T,
fw: bool,
spin: bool,
extra: &str,
) -> rinja::Result<Safe<String>> {
super::render_icon(value.icon_str(), fw, spin, extra)
}

pub fn fab(value: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<Safe<String>> {
IconType::Brand.render(value, fw, spin, extra).map(Safe)
pub fn fab<T: font_awesome_as_a_crate::Brands>(
value: T,
fw: bool,
spin: bool,
extra: &str,
) -> rinja::Result<Safe<String>> {
super::render_icon(value.icon_str(), fw, spin, extra)
}

pub fn highlight(code: impl std::fmt::Display, lang: &str) -> rinja::Result<Safe<String>> {
Expand Down Expand Up @@ -241,59 +255,27 @@ pub mod filters {
}
}

enum IconType {
Strong,
Regular,
Brand,
}

impl fmt::Display for IconType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let icon = match self {
Self::Strong => "solid",
Self::Regular => "regular",
Self::Brand => "brands",
};

f.write_str(icon)
fn render_icon(
icon_str: &str,
fw: bool,
spin: bool,
extra: &str,
) -> rinja::Result<rinja::filters::Safe<String>> {
let mut classes = vec!["fa-svg"];
if fw {
classes.push("fa-svg-fw");
}
}

impl IconType {
fn render(self, icon_name: &str, fw: bool, spin: bool, extra: &str) -> rinja::Result<String> {
let type_ = match self {
IconType::Strong => font_awesome_as_a_crate::Type::Solid,
IconType::Regular => font_awesome_as_a_crate::Type::Regular,
IconType::Brand => font_awesome_as_a_crate::Type::Brands,
};

let icon_file_string = font_awesome_as_a_crate::svg(type_, icon_name).map_err(|err| {
rinja::Error::Custom(
anyhow!(err)
.context(format!(
"error trying to render icon with name \"{}\" and type \"{}\"",
icon_name, type_,
))
.into(),
)
})?;

let mut classes = vec!["fa-svg"];
if fw {
classes.push("fa-svg-fw");
}
if spin {
classes.push("fa-svg-spin");
}
if !extra.is_empty() {
classes.push(extra);
}
let icon = format!(
"\
<span class=\"{class}\" aria-hidden=\"true\">{icon_file_string}</span>",
class = classes.join(" "),
);

Ok(icon)
if spin {
classes.push("fa-svg-spin");
}
if !extra.is_empty() {
classes.push(extra);
}
let icon = format!(
"\
<span class=\"{class}\" aria-hidden=\"true\">{icon_str}</span>",
class = classes.join(" "),
);

Ok(rinja::filters::Safe(icon))
}
12 changes: 6 additions & 6 deletions templates/about-base.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@
<h1 id="crate-title" class="no-description">Docs.rs documentation</h1>
<div class="pure-menu pure-menu-horizontal">
<ul class="pure-menu-list">
{% set text = "circle-info"|fas(false, false, "") %}
{% set text = crate::f_a::icons::IconCircleInfo|fas(false, false, "") %}
{% set text = "{} <span class='title'>About</span>"|format(text) %}
{% call macros::active_link(expected="index", href="/about", text=text) %}

{% set text = "fonticons"|fab(false, false, "") %}
{% set text = crate::f_a::icons::IconFonticons|fab(false, false, "") %}
{% set text = "{} <span class='title'>Badges</span>"|format(text) %}
{% call macros::active_link(expected="badges", href="/about/badges", text=text) %}

{% set text = "gears"|fas(false, false, "") %}
{% set text = crate::f_a::icons::IconGears|fas(false, false, "") %}
{% set text = "{} <span class='title'>Builds</span>"|format(text) %}
{% call macros::active_link(expected="builds", href="/about/builds", text=text) %}

{% set text = "table"|fas(false, false, "") %}
{% set text = crate::f_a::icons::IconTable|fas(false, false, "") %}
{% set text = "{} <span class='title'>Metadata</span>"|format(text) %}
{% call macros::active_link(expected="metadata", href="/about/metadata", text=text) %}

{% set text = "road"|fas(false, false, "") %}
{% set text = crate::f_a::icons::IconRoad|fas(false, false, "") %}
{% set text = "{} <span class='title'>Shorthand URLs</span>"|format(text) %}
{% call macros::active_link(expected="redirections", href="/about/redirections", text=text) %}

{% set text = "download"|fas(false, false, "") %}
{% set text = crate::f_a::icons::IconDownload|fas(false, false, "") %}
{% set text = "{} <span class='title'>Download</span>"|format(text) %}
{% call macros::active_link(expected="download", href="/about/download", text=text) %}
</ul>
Expand Down
4 changes: 2 additions & 2 deletions templates/core/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

{%- block body -%}
<div class="container landing">
<h1 class="brand">{{ "cubes"|fas(false, false, "") }} Docs.rs</h1>
<h1 class="brand">{{ crate::f_a::icons::IconCubes|fas(false, false, "") }} Docs.rs</h1>

<form action="/releases/search" method="GET" class="landing-search-form">
<div>
Expand All @@ -36,7 +36,7 @@ <h1 class="brand">{{ "cubes"|fas(false, false, "") }} Docs.rs</h1>
<strong>Recent Releases</strong>
</a>
<a href="/releases/feed" title="Atom feed">
{{ "square-rss"|fas(false, false, "") }}
{{ crate::f_a::icons::IconSquareRss|fas(false, false, "") }}
</a>
</div>

Expand Down
2 changes: 1 addition & 1 deletion templates/crate/build_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<li>
<a href="/crate/{{ metadata.name }}/{{ metadata.version }}/builds/{{ build_details.id }}/{{ filename }}" class="release">
<div class="pure-g">
<div class="pure-u-1 pure-u-sm-1-24 build">{{ "file-lines"|fas(false, false, "") }}</div>
<div class="pure-u-1 pure-u-sm-1-24 build">{{ crate::f_a::icons::IconFileLines|fas(false, false, "") }}</div>
<div class="pure-u-1 pure-u-sm-10-24">
{% if current_filename.as_deref().unwrap_or_default() == filename.as_str() %}
<b>{{ filename }}</b>
Expand Down
8 changes: 4 additions & 4 deletions templates/crate/builds.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@
<div class="pure-g">
<div class="pure-u-1 pure-u-sm-1-24 build">
{%- if build.build_status == "success" -%}
{{ "check"|fas(false, false, "") }}
{{ crate::f_a::icons::IconCheck|fas(false, false, "") }}
{%- elif build.build_status == "failure" -%}
{{ "triangle-exclamation"|fas(false, false, "") }}
{{ crate::f_a::icons::IconTriangleExclamation|fas(false, false, "") }}
{%- elif build.build_status == "in_progress" -%}
{{ "gear"|fas(false, true, "") }}
{{ crate::f_a::icons::IconGear|fas(false, true, "") }}
{%- else -%}
{{ "x"|fas(false, false, "") }}
{{ crate::f_a::icons::IconX|fas(false, false, "") }}
{%- endif -%}
</div>
<div class="pure-u-1 pure-u-sm-10-24">
Expand Down
18 changes: 9 additions & 9 deletions templates/crate/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
{%- if let Some(homepage_url) = homepage_url -%}
<li class="pure-menu-item">
<a href="{{ homepage_url }}" class="pure-menu-link">
{{ "house"|fas(false, false, "") }} Homepage
{{ crate::f_a::icons::IconHouse|fas(false, false, "") }} Homepage
</a>
</li>
{%- endif -%}
Expand All @@ -52,7 +52,7 @@
{%- if let Some(documentation_url) = documentation_url -%}
<li class="pure-menu-item">
<a href="{{ documentation_url }}" title="Canonical documentation" class="pure-menu-link">
{{ "file-lines"|far(false, false, "") }} Documentation
{{ crate::f_a::icons::IconFileLines|far(false, false, "") }} Documentation
</a>
</li>
{%- endif -%}
Expand All @@ -64,20 +64,20 @@
{# If the repo link is for github or gitlab, show some stats #}
{# TODO: add support for hosts besides github and gitlab (#35) #}
{%- if let Some(repository_metadata) = repository_metadata -%}
{{ "code-branch"|fas(false, false, "") }}
{{ crate::f_a::icons::IconCodeBranch|fas(false, false, "") }}
{% if let Some(name) = repository_metadata.name %}
{{name}}
{% else %}
Repository
{% endif %}
<br>
{{ "star"|fas(false, false, "left-margin") }} {{ repository_metadata.stars }}
{{ "code-branch"|fas(false, false, "") }} {{ repository_metadata.forks }}
{{ "circle-exclamation"|fas(false, false, "") }} {{ repository_metadata.issues }}
{{ crate::f_a::icons::IconStar|fas(false, false, "left-margin") }} {{ repository_metadata.stars }}
{{ crate::f_a::icons::IconCodeBranch|fas(false, false, "") }} {{ repository_metadata.forks }}
{{ crate::f_a::icons::IconCircleExclamation|fas(false, false, "") }} {{ repository_metadata.issues }}

{# If the repo link is unknown, just show a normal link #}
{%- else -%}
{{ "code-branch"|fas(false, false, "") }} Repository
{{ crate::f_a::icons::IconCodeBranch|fas(false, false, "") }} Repository
{%- endif -%}
</a>
</li>
Expand All @@ -87,7 +87,7 @@
<li class="pure-menu-item">
<a href="https://crates.io/crates/{{ name }}" class="pure-menu-link"
title="See {{ name }} on crates.io">
{{ "cube"|fas(false, false, "") }} crates.io
{{ crate::f_a::icons::IconCube|fas(false, false, "") }} crates.io
</a>
</li>

Expand Down Expand Up @@ -160,7 +160,7 @@
</div>
{%- elif build_status == "in_progress" -%}
<div class="info">
{{ "gear"|fas(false, true, "") }}
{{ crate::f_a::icons::IconGear|fas(false, true, "") }}
Build is in progress, it will be available soon
</div>
{%- endif -%}
Expand Down
18 changes: 9 additions & 9 deletions templates/crate/source.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@
{# If we are displaying a file, we also add a button to hide the file sidebar #}
{% if has_file_content %}
<li class="pure-menu-item toggle-source">
<button aria-label="Hide source sidebar" title="Hide source sidebar" aria-expanded="true"><span class="left">{{ "chevron-left"|fas(false, false, "") }}</span><span class="right">{{ "chevron-right"|fas(false, false, "") }}</span> <span class="text">Hide files</span></button>
<button aria-label="Hide source sidebar" title="Hide source sidebar" aria-expanded="true"><span class="left">{{ crate::f_a::icons::IconChevronLeft|fas(false, false, "") }}</span><span class="right">{{ crate::f_a::icons::IconChevronRight|fas(false, false, "") }}</span> <span class="text">Hide files</span></button>
</li>
{% endif %}
{# If this isn't the root folder, show a 'back' button #}
{%- if show_parent_link -%}
<li class="pure-menu-item">
<a href="../" class="pure-menu-link">{{ "folder-open"|far(false, false, "") }} <span class="text">..</span></a>
<a href="../" class="pure-menu-link">{{ crate::f_a::icons::IconFolderOpen|far(false, false, "") }} <span class="text">..</span></a>
</li>
{%- endif -%}

Expand All @@ -48,23 +48,23 @@
<a href="./{{ file.name }}{% if file.mime == "dir" %}/{% endif %}" class="pure-menu-link">
{# Directories #}
{%- if file.mime == "dir" -%}
{{ "folder-open"|far(false, false, "") }}
{{ crate::f_a::icons::IconFolderOpen|far(false, false, "") }}

{# Rust files #}
{%- elif file.mime == "text/rust" -%}
{{ "rust"|fab(false, false, "") }}
{{ crate::f_a::icons::IconRust|fab(false, false, "") }}

{# Cargo.lock #}
{%- elif file.mime == "text/plain" && file.name == "Cargo.lock" -%}
{{ "lock"|fas(false, false, "") }}
{{ crate::f_a::icons::IconLock|fas(false, false, "") }}

{# Markdown files #}
{% elif file.mime == "text/markdown" %}
{{ "markdown"|fab(false, false, "") }}
{{ crate::f_a::icons::IconMarkdown|fab(false, false, "") }}

{# .gitignore #}
{% elif file.mime == "text/plain" && file.name == ".gitignore" %}
{{ "git-alt"|fab(false, false, "") }}
{{ crate::f_a::icons::IconGitAlt|fab(false, false, "") }}

{#
More ideas
Expand All @@ -86,11 +86,11 @@

{# Text files or files which mime starts with `text` #}
{%- elif file.mime == "text/plain" || file.mime|split_first("/") == Some("text") -%}
{{ "file-lines"|far(false, false, "") }}
{{ crate::f_a::icons::IconFileLines|far(false, false, "") }}

{# Binary files and any unrecognized types #}
{% else -%}
{{ "file"|far(false, false, "") }}
{{ crate::f_a::icons::IconFile|far(false, false, "") }}
{%- endif -%}

<span class="text">{{ file.name }}</span>
Expand Down
Loading

0 comments on commit 50d6035

Please sign in to comment.