headers/common/
content_type.rs
1use std::fmt;
2
3use mime::{self, Mime};
4
5#[derive(Clone, Debug, PartialEq)]
40pub struct ContentType(Mime);
41
42impl ContentType {
43 #[inline]
45 pub fn json() -> ContentType {
46 ContentType(mime::APPLICATION_JSON)
47 }
48
49 #[inline]
51 pub fn text() -> ContentType {
52 ContentType(mime::TEXT_PLAIN)
53 }
54
55 #[inline]
57 pub fn text_utf8() -> ContentType {
58 ContentType(mime::TEXT_PLAIN_UTF_8)
59 }
60
61 #[inline]
63 pub fn html() -> ContentType {
64 ContentType(mime::TEXT_HTML)
65 }
66
67 #[inline]
69 pub fn xml() -> ContentType {
70 ContentType(mime::TEXT_XML)
71 }
72
73 #[inline]
75 pub fn form_url_encoded() -> ContentType {
76 ContentType(mime::APPLICATION_WWW_FORM_URLENCODED)
77 }
78 #[inline]
80 pub fn jpeg() -> ContentType {
81 ContentType(mime::IMAGE_JPEG)
82 }
83
84 #[inline]
86 pub fn png() -> ContentType {
87 ContentType(mime::IMAGE_PNG)
88 }
89
90 #[inline]
92 pub fn octet_stream() -> ContentType {
93 ContentType(mime::APPLICATION_OCTET_STREAM)
94 }
95}
96
97impl ::Header for ContentType {
98 fn name() -> &'static ::HeaderName {
99 &::http::header::CONTENT_TYPE
100 }
101
102 fn decode<'i, I: Iterator<Item = &'i ::HeaderValue>>(values: &mut I) -> Result<Self, ::Error> {
103 values
104 .next()
105 .and_then(|v| v.to_str().ok()?.parse().ok())
106 .map(ContentType)
107 .ok_or_else(::Error::invalid)
108 }
109
110 fn encode<E: Extend<::HeaderValue>>(&self, values: &mut E) {
111 let value = self
112 .0
113 .as_ref()
114 .parse()
115 .expect("Mime is always a valid HeaderValue");
116 values.extend(::std::iter::once(value));
117 }
118}
119
120impl From<mime::Mime> for ContentType {
121 fn from(m: mime::Mime) -> ContentType {
122 ContentType(m)
123 }
124}
125
126impl From<ContentType> for mime::Mime {
127 fn from(ct: ContentType) -> mime::Mime {
128 ct.0
129 }
130}
131
132impl fmt::Display for ContentType {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 fmt::Display::fmt(&self.0, f)
135 }
136}
137
138impl std::str::FromStr for ContentType {
139 type Err = ::Error;
140
141 fn from_str(s: &str) -> Result<ContentType, Self::Err> {
142 s.parse::<Mime>()
143 .map(|m| m.into())
144 .map_err(|_| ::Error::invalid())
145 }
146}
147
148#[cfg(test)]
149mod tests {
150 use super::super::test_decode;
151 use super::ContentType;
152
153 #[test]
154 fn json() {
155 assert_eq!(
156 test_decode::<ContentType>(&["application/json"]),
157 Some(ContentType::json()),
158 );
159 }
160
161 #[test]
162 fn from_str() {
163 assert_eq!(
164 "application/json".parse::<ContentType>().unwrap(),
165 ContentType::json(),
166 );
167 assert!("invalid-mimetype".parse::<ContentType>().is_err());
168 }
169
170 bench_header!(bench_plain, ContentType, "text/plain");
171 bench_header!(bench_json, ContentType, "application/json");
172 bench_header!(
173 bench_formdata,
174 ContentType,
175 "multipart/form-data; boundary=---------------abcd"
176 );
177}