Skip to main content

http_type/content_type/
impl.rs

1use super::*;
2
3/// Implementation for `ContentType` enum.
4impl ContentType {
5    /// Serializes data into JSON format.
6    ///
7    /// # Arguments
8    ///
9    /// - `&T` - Data to serialize, which requires the `Serialize` and `Display` bounds
10    ///
11    /// # Returns
12    ///
13    /// - `String` - Serialized JSON string
14    fn get_application_json<T>(data: &T) -> String
15    where
16        T: Serialize + Display,
17    {
18        serde_json::to_string(data).unwrap_or_default()
19    }
20
21    /// Serializes data into XML format.
22    ///
23    /// # Arguments
24    ///
25    /// - `&T` - Data to serialize, which requires the `Serialize` and `Display` bounds
26    ///
27    /// # Returns
28    ///
29    /// - `String` - Serialized XML string
30    fn get_application_xml<T>(data: &T) -> String
31    where
32        T: Serialize + Display,
33    {
34        serde_xml_rs::to_string(data).unwrap_or_default()
35    }
36
37    /// Formats data into plain text.
38    ///
39    /// # Arguments
40    ///
41    /// - `&T` - Data to format, which requires the `Serialize`, `Debug`, `Clone`, `Default` and
42    ///   `Display` bounds
43    ///
44    /// # Returns
45    ///
46    /// - `String` - Formatted plain text
47    fn get_text_plain<T>(data: &T) -> String
48    where
49        T: Serialize + Debug + Clone + Default + Display,
50    {
51        data.to_string()
52    }
53
54    /// Formats data into HTML.
55    ///
56    /// # Arguments
57    ///
58    /// - `&T` - Data to format, which requires the `Serialize`, `Debug`, `Clone` and `Default`
59    ///   bounds
60    ///
61    /// # Returns
62    ///
63    /// - `String` - Formatted HTML
64    fn get_text_html<T>(data: &T) -> String
65    where
66        T: Serialize + Debug + Clone + Default,
67    {
68        let mut html: String = String::with_capacity(64);
69        html.push_str(HTML_TABLE_OPEN);
70        html.push_str(&format!("{data:?}"));
71        html.push_str(HTML_TABLE_CLOSE);
72        html
73    }
74
75    /// Serializes data into URL-encoded format.
76    ///
77    /// # Arguments
78    ///
79    /// - `&T` - Data to serialize, which requires the `Serialize` and `Display` bounds
80    ///
81    /// # Returns
82    ///
83    /// - `String` - URL-encoded string
84    fn get_form_url_encoded<T>(data: &T) -> String
85    where
86        T: Serialize + Display,
87    {
88        serde_urlencoded::to_string(data).unwrap_or_default()
89    }
90
91    /// Formats data as hexadecimal string.
92    ///
93    /// # Arguments
94    ///
95    /// - `&T` - Data to format, which requires the `Serialize`, `Debug`, `Clone`, `Default` and
96    ///   `Display` bounds
97    ///
98    /// # Returns
99    ///
100    /// - `String` - Hexadecimal encoded string
101    fn get_binary<T>(data: &T) -> String
102    where
103        T: Serialize + Debug + Clone + Default + Display,
104    {
105        hex::encode(data.to_string())
106    }
107
108    /// Gets formatted body string for content type.
109    ///
110    /// # Arguments
111    ///
112    /// - `&T` - Data to format, which requires the `Serialize`, `Debug`, `Clone`, `Default` and
113    ///   `Display` bounds
114    ///
115    /// # Returns
116    ///
117    /// - `String` - Formatted body string
118    pub fn get_body_string<T>(&self, data: &T) -> String
119    where
120        T: Serialize + Debug + Clone + Default + Display,
121    {
122        match self {
123            Self::ApplicationJson => Self::get_application_json(data),
124            Self::ApplicationXml => Self::get_application_xml(data),
125            Self::TextPlain => Self::get_text_plain(data),
126            Self::TextHtml => Self::get_text_html(data),
127            Self::FormUrlEncoded => Self::get_form_url_encoded(data),
128            Self::Unknown => Self::get_binary(data),
129        }
130    }
131
132    /// Formats content type with charset.
133    ///
134    /// # Arguments
135    ///
136    /// - `T` - Content type, which requires the `AsRef<str>` bound
137    /// - `S` - Charset, which requires the `AsRef<str>` bound
138    ///
139    /// # Returns
140    ///
141    /// - `String` - Formatted string
142    pub fn format_content_type_with_charset<T, S>(content_type: T, charset: S) -> String
143    where
144        T: AsRef<str>,
145        S: AsRef<str>,
146    {
147        let content_type_ref: &str = content_type.as_ref();
148        let charset_ref: &str = charset.as_ref();
149        let mut result: String = String::with_capacity(
150            content_type_ref.len()
151                + SEMICOLON_SPACE.len()
152                + CHARSET_EQUAL.len()
153                + charset_ref.len(),
154        );
155        result.push_str(content_type_ref);
156        result.push_str(SEMICOLON_SPACE);
157        result.push_str(CHARSET_EQUAL);
158        result.push_str(charset_ref);
159        result
160    }
161
162    /// Formats content type with charset declaration.
163    ///
164    /// # Arguments
165    ///
166    /// - `T` - Content type, which requires the `AsRef<str>` bound
167    /// - `S` - Charset declaration, which requires the `AsRef<str>` bound
168    ///
169    /// # Returns
170    ///
171    /// - `String` - Formatted string
172    pub fn format_content_type_with_charset_declaration<T, S>(
173        content_type: T,
174        charset_with_key: S,
175    ) -> String
176    where
177        T: AsRef<str>,
178        S: AsRef<str>,
179    {
180        let content_type_ref: &str = content_type.as_ref();
181        let charset_with_key_ref: &str = charset_with_key.as_ref();
182        let mut result: String = String::with_capacity(
183            content_type_ref.len() + SEMICOLON_SPACE.len() + charset_with_key_ref.len(),
184        );
185        result.push_str(content_type_ref);
186        result.push_str(SEMICOLON_SPACE);
187        result.push_str(charset_with_key_ref);
188        result
189    }
190}
191
192/// Implements `FromStr` for `ContentType`.
193impl FromStr for ContentType {
194    type Err = ();
195
196    /// Parses string into ContentType.
197    ///
198    /// # Arguments
199    ///
200    /// - `&str` - String to parse
201    ///
202    /// # Returns
203    ///
204    /// - `Result<Self, Self::Err>` - Parse result
205    fn from_str(data: &str) -> Result<Self, Self::Err> {
206        match data.to_ascii_lowercase().as_str() {
207            APPLICATION_JSON => Ok(Self::ApplicationJson),
208            APPLICATION_XML => Ok(Self::ApplicationXml),
209            TEXT_PLAIN => Ok(Self::TextPlain),
210            TEXT_HTML => Ok(Self::TextHtml),
211            FORM_URLENCODED => Ok(Self::FormUrlEncoded),
212            _ => Ok(Self::Unknown),
213        }
214    }
215}