http_type/content_type/impl.rs
1use crate::*;
2
3impl ContentType {
4 /// Handles the `application/json` Content-Type by serializing the provided data
5 /// into a JSON string.
6 ///
7 /// # Type Parameters
8 /// - `T`: The type of the data to be serialized, which must implement `Serialize`.
9 ///
10 /// # Parameters
11 /// - `data`: The data to be serialized into JSON.
12 ///
13 /// # Returns
14 /// A string containing the serialized JSON representation of the provided data.
15 /// If serialization fails, it returns an empty JSON object (`{}`).
16 fn get_application_json<T>(data: &T) -> String
17 where
18 T: Serialize + Display,
19 {
20 json_to_string(data).unwrap_or_else(|_| "{}".to_string())
21 }
22
23 /// Handles the `application/xml` Content-Type by serializing the provided data
24 /// into an XML string.
25 ///
26 /// # Type Parameters
27 /// - `T`: The type of the data to be serialized, which must implement `Serialize`.
28 ///
29 /// # Parameters
30 /// - `data`: The data to be serialized into XML.
31 ///
32 /// # Returns
33 /// A string containing the serialized XML representation of the provided data.
34 /// If serialization fails, it returns an empty XML root element (`<root></root>`).
35 fn get_application_xml<T>(data: &T) -> String
36 where
37 T: Serialize + Display,
38 {
39 serde_xml_rs::to_string(data).unwrap_or_else(|_| "<root></root>".to_string())
40 }
41
42 /// Handles the `text/plain` Content-Type by formatting the provided data
43 /// into a plain text string.
44 ///
45 /// # Type Parameters
46 /// - `T`: The type of the data to be formatted, which must implement `Serialize`, `Debug`, `Clone`, and `Default`.
47 ///
48 /// # Parameters
49 /// - `data`: The data to be formatted into plain text.
50 ///
51 /// # Returns
52 /// A plain text string representing the provided data, formatted with the `Debug` trait.
53 fn get_text_plain<T>(data: &T) -> String
54 where
55 T: Serialize + Debug + Clone + Default + Display,
56 {
57 data.to_string()
58 }
59
60 /// Handles the `text/html` Content-Type by formatting the provided data
61 /// into an HTML string, typically inside a simple table.
62 ///
63 /// # Type Parameters
64 /// - `T`: The type of the data to be formatted, which must implement `Serialize`, `Debug`, `Clone`, and `Default`.
65 ///
66 /// # Parameters
67 /// - `data`: The data to be formatted into HTML.
68 ///
69 /// # Returns
70 /// A string containing the HTML representation of the provided data, inside a table row.
71 fn get_text_html<T>(data: &T) -> String
72 where
73 T: Serialize + Debug + Clone + Default,
74 {
75 let mut html: String = String::with_capacity(64);
76 html.push_str("<table><tr><td>");
77 html.push_str(&format!("{:?}", data));
78 html.push_str("</td></tr></table>");
79 html
80 }
81
82 /// Handles the `application/x-www-form-urlencoded` Content-Type by serializing
83 /// the provided data into a URL-encoded string.
84 ///
85 /// # Type Parameters
86 /// - `T`: The type of the data to be serialized, which must implement `Serialize`.
87 ///
88 /// # Parameters
89 /// - `data`: The data to be serialized into URL-encoded format.
90 ///
91 /// # Returns
92 /// A string containing the URL-encoded representation of the provided data.
93 /// If serialization fails, it returns an empty string.
94 fn get_form_url_encoded<T>(data: &T) -> String
95 where
96 T: Serialize + Display,
97 {
98 serde_urlencoded::to_string(data).unwrap_or_else(|_| String::new())
99 }
100
101 /// Handles binary data when the `Content-Type` is unknown by formatting the
102 /// provided data as a hexadecimal string.
103 ///
104 /// # Type Parameters
105 /// - `T`: The type of the data to be formatted, which must implement `Serialize`, `Debug`, `Clone`, and `Default`.
106 ///
107 /// # Parameters
108 /// - `data`: The data to be formatted into binary representation.
109 ///
110 /// # Returns
111 /// A string containing the hexadecimal encoding of the provided data.
112 fn get_binary<T>(data: &T) -> String
113 where
114 T: Serialize + Debug + Clone + Default + Display,
115 {
116 hex::encode(data.to_string())
117 }
118
119 /// Public interface for getting a formatted body string based on the `ContentType`.
120 ///
121 /// This method routes the data to the appropriate handler method based on the
122 /// `ContentType`, formatting the body accordingly.
123 ///
124 /// # Type Parameters
125 /// - `T`: The type of the data to be formatted, which must implement `Serialize`, `Debug`, `Clone`, and `Default`.
126 ///
127 /// # Parameters
128 /// - `data`: The data to be formatted into the body string.
129 ///
130 /// # Returns
131 /// A string containing the formatted body based on the content type, such as JSON, XML, plain text, HTML, etc.
132 pub fn get_body_string<T>(&self, data: &T) -> String
133 where
134 T: Serialize + Debug + Clone + Default + Display,
135 {
136 match self {
137 Self::ApplicationJson => Self::get_application_json(data),
138 Self::ApplicationXml => Self::get_application_xml(data),
139 Self::TextPlain => Self::get_text_plain(data),
140 Self::TextHtml => Self::get_text_html(data),
141 Self::FormUrlEncoded => Self::get_form_url_encoded(data),
142 Self::Unknown => Self::get_binary(data),
143 }
144 }
145
146 /// Formats a content type with a charset value.
147 ///
148 /// # Parameters
149 /// - `content_type`: The content type.
150 /// - `charset`: The character set.
151 ///
152 /// # Returns
153 /// A format string.
154 pub fn format_content_type_with_charset(content_type: &str, charset: &str) -> String {
155 let mut result: String = String::with_capacity(
156 content_type.len() + SEMICOLON_SPACE.len() + CHARSET_EQUAL.len() + charset.len(),
157 );
158 result.push_str(content_type);
159 result.push_str(SEMICOLON_SPACE);
160 result.push_str(CHARSET_EQUAL);
161 result.push_str(charset);
162 result
163 }
164
165 /// Formats a content type with a full charset declaration.
166 ///
167 /// # Parameters
168 /// - `content_type`: The content type.
169 /// - `charset_with_key`: The charset declaration.
170 ///
171 /// # Returns
172 /// A format string like `"text/html; charset=utf-8"`.
173 pub fn format_content_type_with_charset_declaration(
174 content_type: &str,
175 charset_with_key: &str,
176 ) -> String {
177 let mut result: String = String::with_capacity(
178 content_type.len() + SEMICOLON_SPACE.len() + charset_with_key.len(),
179 );
180 result.push_str(content_type);
181 result.push_str(SEMICOLON_SPACE);
182 result.push_str(charset_with_key);
183 result
184 }
185}
186
187impl FromStr for ContentType {
188 type Err = ();
189
190 fn from_str(data: &str) -> Result<Self, Self::Err> {
191 match data.to_ascii_lowercase().as_str() {
192 APPLICATION_JSON => Ok(Self::ApplicationJson),
193 APPLICATION_XML => Ok(Self::ApplicationXml),
194 TEXT_PLAIN => Ok(Self::TextPlain),
195 TEXT_HTML => Ok(Self::TextHtml),
196 FORM_URLENCODED => Ok(Self::FormUrlEncoded),
197 _ => Ok(Self::Unknown),
198 }
199 }
200}
201
202impl Default for ContentType {
203 fn default() -> Self {
204 Self::Unknown
205 }
206}