RocketでTemplateをバイナリに埋め込む方法

1 min read読了の目安(約1500字

レアケースだと思いますが、残しておきます。

Rocket とは

Rust製のシンプルなWebフレームワーク

API特化というわけではなく、HandlebarsTeraなどのHTMLのテンプレートエンジンにも対応しているWebフレームワークです。

やりたいこと

出力されるバイナリにHTMLのテンプレートファイルを埋め込んでしまいたい。

諸事情によりバイナリぽんで動くWebアプリが作りたかったのだが、普通に構築するとHTML等はバイナリと別で配置する前提なので。

オプションが存在するか?

調べたが存在しない。

クレートはあるか?

次のクレートが存在するが、ちょうど本家の0.5.0に追従しようとしてバージョンアップしているタイミングで挙動が怪しいので見送り。exampleも動かず断念。

最終的に上手くいった方法

  • 自前でHandelebarsを呼び出す。
  • コンパイル時に文字列としてテンプレート文字列を読み込む
main.rs
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate rocket;

use handlebars::Handlebars;
use rocket::response::content;

#[derive(serde::Serialize)]
struct TemplateContext {
    name: String,
}

#[get("/")]
fn index() -> content::Html<String> {
    let reg = Handlebars::new();
    let rendered = reg
        .render_template(
            include_str!("../templates/index.html.hbs"),
            &TemplateContext {
                name: String::from("Yamada Taro"),
            },
        )
        .unwrap();
    content::Html(rendered)
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
index.html.hbs
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test</title>
</head>
<body>
Hello, {{name}}
</body>
</html>

ただし開発中のLive Reloadingは動作しなくなるので注意。
ただこれだとRocket使う意味はあまりないですね・・・

成果物

https://github.com/corocn/sss