47 个版本

0.19.18 2024年1月30日
0.19.16 2023年11月25日
0.19.15 2023年7月2日
0.19.13 2023年1月23日
0.19.1 2022年2月28日

#53解析器实现

Download history 21357/week @ 2024-04-22 20409/week @ 2024-04-29 23886/week @ 2024-05-06 23558/week @ 2024-05-13 22780/week @ 2024-05-20 21146/week @ 2024-05-27 22960/week @ 2024-06-03 21128/week @ 2024-06-10 20255/week @ 2024-06-17 23293/week @ 2024-06-24 19158/week @ 2024-07-01 21518/week @ 2024-07-08 24057/week @ 2024-07-15 24771/week @ 2024-07-22 25609/week @ 2024-07-29 25195/week @ 2024-08-05

100,766 每月下载量
用于 64 仓库 (直接使用26个)

MIT 许可证

290KB
1.5K SLoC

MediaType

Rust的MIME媒体类型解析

Crates.io dependency status GitHub license Rustdoc Rust

解析

MediaType::parse 执行零拷贝解析:一个 MediaType 借用了输入字符串而不是复制它。

如果需要一个拥有类型,请使用 MediaTypeBuf

use mediatype::{names::*, values::*, MediaType};

let madia_type = "image/svg+xml; charset=UTF-8";
let svg = MediaType::parse(madia_type).unwrap();

assert_eq!(svg.ty, IMAGE);
assert_eq!(svg.subty, SVG);
assert_eq!(svg.suffix, Some(XML));
assert_eq!(svg.get_param(CHARSET), Some(UTF_8));

构建

MediaType 是 const-constructible。它可以定义为常量。

预定义的名称和值定义在 namesvalues 模块中。

use mediatype::{names::*, values::*, media_type, MediaType};

const TEXT_PLAIN: MediaType = MediaType::new(TEXT, PLAIN);

const IMAGE_SVG: MediaType = 
  MediaType::from_parts(TEXT, PLAIN, Some(XML), &[(CHARSET, UTF_8)]);

const TEXT_MARKDOWN: MediaType = 
  media_type!(TEXT/MARKDOWN; CHARSET=UTF_8);

参数

大小写敏感

比较时不区分大小写,除非是参数值。

let text_plain_lower = MediaType::parse("text/plain; charset=UTF-8").unwrap();
let text_plain_upper = MediaType::parse("TEXT/PLAIN; CHARSET=UTF-8").unwrap();

assert_eq!(text_plain_lower, text_plain_upper);
assert_eq!(text_plain_lower.ty(), "Text");
assert_eq!(text_plain_upper.subty(), "Plain");
assert!(text_plain_lower != 
  MediaType::parse("text/plain; charset=utf-8").unwrap());

重复参数名称

解析器不会将重复的参数名称报告为错误,但 MediaType 只识别最后一个值。

let text_plain = MediaType::parse(
  "text/plain; charset=US-ASCII; charset=UTF-8").unwrap();

assert_eq!(
    text_plain.to_string(),
    "text/plain; charset=US-ASCII; charset=UTF-8"
);

// Return the last charset value.
assert_eq!(text_plain.get_param(CHARSET), Some(UTF_8));

// Compare the last charset value.
assert_eq!(
    text_plain,
    MediaType::parse("text/plain; charset=UTF-8").unwrap()
);

拥有类型

MediaTypeBufMediaType 的拥有版本。它是不可变的,但针对最小堆栈和堆使用进行了优化。

use mediatype::{names::*, values::*, MediaType, MediaTypeBuf};

let text_plain: MediaTypeBuf = "text/plain; charset=UTF-8".parse().unwrap();
assert_eq!(text_plain.get_param(CHARSET).unwrap(), UTF_8);

// Convert to MediaType
let mut text_markdown: MediaType = text_plain.to_ref();
text_markdown.subty = MARKDOWN;
assert_eq!(text_markdown.to_string(), "text/markdown; charset=UTF-8");

MediaTypeList

MediaTypeList 解析 HTTP Accept 标头中使用的逗号分隔的 MediaType 列表。(RFC 7231)

use mediatype::{MediaType, MediaTypeList};

let mut list = MediaTypeList::new(
    "text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8",
);
assert_eq!(list.next(), Some(MediaType::parse("text/html")));
assert_eq!(list.next(), Some(MediaType::parse("application/xhtml+xml")));
assert_eq!(list.next(), Some(MediaType::parse("application/xml;q=0.9")));
assert_eq!(list.next(), Some(MediaType::parse("*/*;q=0.8")));
assert_eq!(list.next(), None);

序列化和反序列化

要启用序列化和反序列化,请指定 Cargo.toml 中的 serde 功能。

mediatype = { version = "...", features = ["serde"] }
let json = r#"
    [
        "text/plain",
        "image/svg+xml; charset=UTF-8"
    ]
"#;

let decoded: Vec<MediaType> = serde_json::from_str(json).unwrap();

依赖项