Skip to content

Commit 3c23b3e

Browse files
committed
middleware: Serve svelte/build/200.html file under /svelte paths
1 parent 733a221 commit 3c23b3e

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

src/middleware/ember_html.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,54 @@ use url::Url;
2222
use crate::app::AppState;
2323

2424
const OG_IMAGE_FALLBACK_URL: &str = "https://crates.io/assets/og-image.png";
25-
const INDEX_TEMPLATE_NAME: &str = "index_html";
2625
const PATH_PREFIX_CRATES: &str = "/crates/";
2726

27+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28+
enum FrontendApp {
29+
Ember,
30+
Svelte,
31+
}
32+
33+
impl FrontendApp {
34+
fn from_path(path: &str) -> Self {
35+
if path.starts_with("/svelte/") {
36+
FrontendApp::Svelte
37+
} else {
38+
FrontendApp::Ember
39+
}
40+
}
41+
42+
fn index_template_name(&self) -> &'static str {
43+
match self {
44+
FrontendApp::Ember => "index_html",
45+
FrontendApp::Svelte => "svelte_index_html",
46+
}
47+
}
48+
}
49+
2850
/// The [`Shared`] allows for multiple tasks to wait on a single future, [`BoxFuture`] allows
2951
/// us to name the type in the declaration of static variables, and the [`Arc`] ensures
3052
/// the [`minijinja::Environment`] doesn't get cloned each request.
3153
type TemplateEnvFut = Shared<BoxFuture<'static, Arc<minijinja::Environment<'static>>>>;
32-
type TemplateCache = moka::future::Cache<Cow<'static, str>, String>;
54+
type TemplateCache = moka::future::Cache<(Cow<'static, str>, FrontendApp), String>;
3355

3456
/// Initialize [`minijinja::Environment`] given the index.html file at `dist/index.html`.
3557
/// This should only be done once as it will load said file from persistent storage.
3658
async fn init_template_env() -> Arc<minijinja::Environment<'static>> {
59+
let mut env = minijinja::Environment::empty();
60+
3761
let template_j2 = tokio::fs::read_to_string("dist/index.html")
3862
.await
3963
.expect("Error loading dist/index.html template. Is the frontend package built yet?");
4064

41-
let mut env = minijinja::Environment::empty();
42-
env.add_template_owned(INDEX_TEMPLATE_NAME, template_j2)
65+
env.add_template_owned(FrontendApp::Ember.index_template_name(), template_j2)
4366
.expect("Error loading template");
67+
68+
if let Ok(svelte_template) = tokio::fs::read_to_string("svelte/build/200.html").await {
69+
env.add_template_owned(FrontendApp::Svelte.index_template_name(), svelte_template)
70+
.expect("Error loading Svelte template");
71+
}
72+
4473
Arc::new(env)
4574
}
4675

@@ -83,8 +112,10 @@ pub async fn serve_html(state: AppState, request: Request, next: Next) -> Respon
83112
let html_cache = RENDERED_HTML_CACHE
84113
.get_or_init(|| init_html_cache(state.config.html_render_cache_max_capacity));
85114

115+
let frontend_app = FrontendApp::from_path(path);
116+
86117
let render_result = html_cache
87-
.entry_by_ref(&og_image_url)
118+
.entry_by_ref(&(og_image_url.clone(), frontend_app))
88119
.or_try_insert_with::<_, minijinja::Error>(async {
89120
// `LazyLock::deref` blocks as long as its initializer is running in another thread.
90121
// Note that this won't take long, as the constructed Futures are not awaited
@@ -94,7 +125,7 @@ pub async fn serve_html(state: AppState, request: Request, next: Next) -> Respon
94125
// Render the HTML given the OG image URL
95126
let env = template_env.clone().await;
96127
let html = env
97-
.get_template(INDEX_TEMPLATE_NAME)?
128+
.get_template(frontend_app.index_template_name())?
98129
.render(minijinja::context! { og_image_url})?;
99130

100131
Ok(html)

0 commit comments

Comments
 (0)