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}