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}