Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

メディアタイプ

文字列から MIME タイプを取得する

mime-badge cat-encoding-badge

次の例では、mime クレートを使用して文字列から MIME タイプをパースする方法を示します。FromStrError は、unwrap_or 句でデフォルトの MIME タイプを生成します。

use mime::{Mime, APPLICATION_OCTET_STREAM};

fn main() {
    let invalid_mime_type = "i n v a l i d";
    let default_mime = invalid_mime_type
        .parse::<Mime>()
        .unwrap_or(APPLICATION_OCTET_STREAM);

    println!(
        "MIME for {:?} used default value {:?}",
        invalid_mime_type, default_mime
    );

    let valid_mime_type = "TEXT/PLAIN";
    let parsed_mime = valid_mime_type
        .parse::<Mime>()
        .unwrap_or(APPLICATION_OCTET_STREAM);

    println!(
        "MIME for {:?} was parsed as {:?}",
        valid_mime_type, parsed_mime
    );
}

ファイル名から MIME タイプを取得する

mime-badge cat-encoding-badge

次の例では、mime クレートを使用して、与えられた ファイル名から正しい MIME タイプを返す方法を示します。プログラムはファイル拡張子を 確認し、既知のリストと照合します。戻り値は mime:Mime です。

use mime::Mime;

fn find_mimetype (filename : &String) -> Mime{

    let parts : Vec<&str> = filename.split('.').collect();

    let res = match parts.last() {
            Some(v) =>
                match *v {
                    "png" => mime::IMAGE_PNG,
                    "jpg" => mime::IMAGE_JPEG,
                    "json" => mime::APPLICATION_JSON,
                    &_ => mime::TEXT_PLAIN,
                },
            None => mime::TEXT_PLAIN,
        };
    return res;
}

fn main() {
    let filenames = vec!("foobar.jpg", "foo.bar", "foobar.png");
    for file in filenames {
	    let mime = find_mimetype(&file.to_owned());
	 	println!("MIME for {}: {}", file, mime);
	 }

}

HTTP レスポンスの MIME タイプを解析する

reqwest-badge mime-badge cat-net-badge cat-encoding-badge

reqwest から HTTP レスポンスを受け取ると、MIME type またはメディアタイプは Content-Type ヘッダーに含まれていることがあります。reqwest::header::HeaderMap::get は このヘッダーを reqwest::header::HeaderValue として取得し、これは文字列に変換できます。 その後 mime クレートでそれを解析すると、mime::Mime 値が得られます。

mime クレートでは、よく使われる MIME タイプもいくつか定義されています。

なお、reqwest::header モジュールは http クレートからエクスポートされています。

use anyhow::Result;
use mime::Mime;
use std::str::FromStr;
use reqwest::header::CONTENT_TYPE;

#[tokio::main]
async fn main() -> Result<()> {
    let response = reqwest::get("https://www.rust-lang.org/logos/rust-logo-32x32.png").await?;
    let headers = response.headers();

    match headers.get(CONTENT_TYPE) {
        None => {
            println!("The response does not contain a Content-Type header.");
        }
        Some(content_type) => {
            let content_type = Mime::from_str(content_type.to_str()?)?;
            let media_type = match (content_type.type_(), content_type.subtype()) {
                (mime::TEXT, mime::HTML) => "a HTML document",
                (mime::TEXT, _) => "a text document",
                (mime::IMAGE, mime::PNG) => "a PNG image",
                (mime::IMAGE, _) => "an image",
                _ => "neither text nor image",
            };

            println!("The reponse contains {}.", media_type);
        }
    };

    Ok(())
}