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