fire_http_representation/header/
contenttype.rs

1//! Types related to the `ContentType` http header.
2//!
3//! ## Note
4//! These are the most basic types, types that can be utf8 are always utf8
5//! Todo this should be redone once a clear successor of mime is available.
6
7use super::HeaderValue;
8
9use std::fmt;
10use std::str::FromStr;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub struct Mime(MimeValue);
14
15impl Mime {
16	/// Create a Mime Type from a file extension.
17	pub fn from_extension(ext: &str) -> Option<Self> {
18		MimeValue::from_extension(ext).map(Self)
19	}
20
21	pub fn extension(&self) -> &'static str {
22		self.0.extension()
23	}
24
25	pub fn as_str(&self) -> &'static str {
26		self.0.as_str()
27	}
28
29	pub fn as_str_with_maybe_charset(&self) -> &'static str {
30		self.0.as_str_with_maybe_charset()
31	}
32}
33
34impl fmt::Display for Mime {
35	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36		f.write_str(self.as_str())
37	}
38}
39
40include!(concat!(env!("OUT_DIR"), "/mime.rs"));
41
42impl FromStr for Mime {
43	type Err = ();
44
45	fn from_str(s: &str) -> Result<Self, ()> {
46		MimeValue::from_str(s).map(Self).ok_or(())
47	}
48}
49
50/// Http `ContentType` header.
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum ContentType {
53	None,
54	Known(Mime),
55	Unknown(String),
56}
57
58impl ContentType {
59	pub fn as_str(&self) -> &str {
60		match self {
61			Self::Known(m) => m.0.as_str_with_maybe_charset(),
62			Self::Unknown(s) => &s,
63			Self::None => "",
64		}
65	}
66
67	pub fn from_extension(e: &str) -> Option<Self> {
68		Some(Self::Known(Mime::from_extension(e)?))
69	}
70}
71
72impl fmt::Display for ContentType {
73	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74		f.write_str(self.as_str())
75	}
76}
77
78impl From<()> for ContentType {
79	fn from(_: ()) -> Self {
80		Self::None
81	}
82}
83
84impl From<Mime> for ContentType {
85	fn from(m: Mime) -> Self {
86		Self::Known(m)
87	}
88}
89
90impl From<String> for ContentType {
91	fn from(s: String) -> Self {
92		match Mime::from_str(&s) {
93			Ok(m) => Self::Known(m),
94			Err(_) => Self::Unknown(s),
95		}
96	}
97}
98
99impl<'a> From<&'a str> for ContentType {
100	fn from(s: &'a str) -> Self {
101		match Mime::from_str(s) {
102			Ok(m) => Self::Known(m),
103			Err(_) => Self::Unknown(s.to_string()),
104		}
105	}
106}
107
108impl TryFrom<ContentType> for HeaderValue {
109	type Error = super::values::InvalidHeaderValue;
110
111	fn try_from(ct: ContentType) -> Result<Self, Self::Error> {
112		match ct {
113			ContentType::None => Ok(Self::from_static("")),
114			ContentType::Known(m) => {
115				Ok(Self::from_static(m.as_str_with_maybe_charset()))
116			}
117			ContentType::Unknown(s) => s.try_into(),
118		}
119	}
120}