RocketでカスタムContentTypeを作りレスポンスヘッダに設定する

Responses - Rocket Programming Guide

ドキュメントの Responses のページの Rocket Responders にある通り、 Content という Responder が ContentType を書き換えるために使える。

テンプレートをレンダリングして返す場合は Content<Template> を返すように定義して、下記のようにする(実際にはエラー処理するので Result を使うだろう)

fn custom() -> Content<Template> {
    let context = ...;
    Content(CustomContentType, Template::render("template_name", &context))
}

Contentの第一引数に渡す ContentType はHTMLとかJSONとか主要なContentTypeは定義されているが、定義されていないようなものを使う場合自分で作る。

使い回すし const で定義するとなると多分こんな感じになるんだけど、privateという名前のmodule以下の構造体使わないといけないので微妙。

use rocket::http::{ContentType, MediaType};
use rocket::http::private::{Source, MediaParams, Indexed};
use std::borrow::Cow;

pub const TURBO_STREAM_CONTENT_TYPE: ContentType = ContentType(MediaType {
    source: Source::None,
    top: Indexed::Concrete(Cow::Borrowed("text")),
    sub: Indexed::Concrete(Cow::Borrowed("vnd.turbo-stream.html")),
    params: MediaParams::Static(&[])
});

公開されているコンストラクタを使うと普通の conststatic にはできないので、 lazy_static! とかを使って普通に用意されているメソッドを使って作るのがいいのかなー?