logged_stream/
buffer_formatter.rs1const DEFAULT_SEPARATOR: &str = ":";
2
3pub trait BufferFormatter: Send + 'static {
13 fn get_separator(&self) -> &str;
18
19 fn format_byte(&self, byte: &u8) -> String;
21
22 fn format_buffer(&self, buffer: &[u8]) -> String {
24 buffer
25 .iter()
26 .map(|b| self.format_byte(b))
27 .collect::<Vec<String>>()
28 .join(self.get_separator())
29 }
30}
31
32impl BufferFormatter for Box<dyn BufferFormatter> {
33 #[inline]
34 fn get_separator(&self) -> &str {
35 (**self).get_separator()
36 }
37
38 #[inline]
39 fn format_byte(&self, byte: &u8) -> String {
40 (**self).format_byte(byte)
41 }
42}
43
44#[derive(Debug, Clone)]
50pub struct DecimalFormatter {
51 separator: String,
52}
53
54impl DecimalFormatter {
55 pub fn new(provided_separator: Option<&str>) -> Self {
58 Self::new_owned(provided_separator.map(ToString::to_string))
59 }
60
61 pub fn new_owned(provided_separator: Option<String>) -> Self {
64 Self {
65 separator: provided_separator.unwrap_or(DEFAULT_SEPARATOR.to_string()),
66 }
67 }
68
69 pub fn new_default() -> Self {
71 Self::new_owned(None)
72 }
73}
74
75impl BufferFormatter for DecimalFormatter {
76 #[inline]
77 fn get_separator(&self) -> &str {
78 self.separator.as_str()
79 }
80
81 #[inline]
82 fn format_byte(&self, byte: &u8) -> String {
83 format!("{byte}")
84 }
85}
86
87impl BufferFormatter for Box<DecimalFormatter> {
88 #[inline]
89 fn get_separator(&self) -> &str {
90 (**self).get_separator()
91 }
92
93 #[inline]
94 fn format_byte(&self, byte: &u8) -> String {
95 (**self).format_byte(byte)
96 }
97}
98
99impl Default for DecimalFormatter {
100 fn default() -> Self {
101 Self::new_default()
102 }
103}
104
105#[derive(Debug, Clone)]
111pub struct OctalFormatter {
112 separator: String,
113}
114
115impl OctalFormatter {
116 pub fn new(provided_separator: Option<&str>) -> Self {
119 Self::new_owned(provided_separator.map(ToString::to_string))
120 }
121
122 pub fn new_owned(provided_separator: Option<String>) -> Self {
125 Self {
126 separator: provided_separator.unwrap_or(DEFAULT_SEPARATOR.to_string()),
127 }
128 }
129
130 pub fn new_default() -> Self {
132 Self::new_owned(None)
133 }
134}
135
136impl BufferFormatter for OctalFormatter {
137 #[inline]
138 fn get_separator(&self) -> &str {
139 self.separator.as_str()
140 }
141
142 #[inline]
143 fn format_byte(&self, byte: &u8) -> String {
144 format!("{byte:03o}")
145 }
146}
147
148impl BufferFormatter for Box<OctalFormatter> {
149 #[inline]
150 fn get_separator(&self) -> &str {
151 (**self).get_separator()
152 }
153
154 #[inline]
155 fn format_byte(&self, byte: &u8) -> String {
156 (**self).format_byte(byte)
157 }
158}
159
160impl Default for OctalFormatter {
161 fn default() -> Self {
162 Self::new_default()
163 }
164}
165
166#[derive(Debug, Clone)]
172pub struct UppercaseHexadecimalFormatter {
173 separator: String,
174}
175
176impl UppercaseHexadecimalFormatter {
177 pub fn new(provided_separator: Option<&str>) -> Self {
180 Self::new_owned(provided_separator.map(ToString::to_string))
181 }
182
183 pub fn new_owned(provided_separator: Option<String>) -> Self {
186 Self {
187 separator: provided_separator.unwrap_or(DEFAULT_SEPARATOR.to_string()),
188 }
189 }
190
191 pub fn new_default() -> Self {
193 Self::new_owned(None)
194 }
195}
196
197impl BufferFormatter for UppercaseHexadecimalFormatter {
198 #[inline]
199 fn get_separator(&self) -> &str {
200 self.separator.as_str()
201 }
202
203 #[inline]
204 fn format_byte(&self, byte: &u8) -> String {
205 format!("{byte:02X}")
206 }
207}
208
209impl BufferFormatter for Box<UppercaseHexadecimalFormatter> {
210 #[inline]
211 fn get_separator(&self) -> &str {
212 (**self).get_separator()
213 }
214
215 #[inline]
216 fn format_byte(&self, byte: &u8) -> String {
217 (**self).format_byte(byte)
218 }
219}
220
221impl Default for UppercaseHexadecimalFormatter {
222 fn default() -> Self {
223 Self::new_default()
224 }
225}
226
227#[derive(Debug, Clone)]
233pub struct LowercaseHexadecimalFormatter {
234 separator: String,
235}
236
237impl LowercaseHexadecimalFormatter {
238 pub fn new(provided_separator: Option<&str>) -> Self {
241 Self::new_owned(provided_separator.map(ToString::to_string))
242 }
243
244 pub fn new_owned(provided_separator: Option<String>) -> Self {
247 Self {
248 separator: provided_separator.unwrap_or(DEFAULT_SEPARATOR.to_string()),
249 }
250 }
251
252 pub fn new_default() -> Self {
254 Self::new_owned(None)
255 }
256}
257
258impl BufferFormatter for LowercaseHexadecimalFormatter {
259 #[inline]
260 fn get_separator(&self) -> &str {
261 self.separator.as_str()
262 }
263
264 #[inline]
265 fn format_byte(&self, byte: &u8) -> String {
266 format!("{byte:02x}")
267 }
268}
269
270impl BufferFormatter for Box<LowercaseHexadecimalFormatter> {
271 #[inline]
272 fn get_separator(&self) -> &str {
273 (**self).get_separator()
274 }
275
276 #[inline]
277 fn format_byte(&self, byte: &u8) -> String {
278 (**self).format_byte(byte)
279 }
280}
281
282impl Default for LowercaseHexadecimalFormatter {
283 fn default() -> Self {
284 Self::new_default()
285 }
286}
287
288#[derive(Debug, Clone)]
294pub struct BinaryFormatter {
295 separator: String,
296}
297
298impl BinaryFormatter {
299 pub fn new(provided_separator: Option<&str>) -> Self {
302 Self::new_owned(provided_separator.map(ToString::to_string))
303 }
304
305 pub fn new_owned(provided_separator: Option<String>) -> Self {
308 Self {
309 separator: provided_separator.unwrap_or(DEFAULT_SEPARATOR.to_string()),
310 }
311 }
312
313 pub fn new_default() -> Self {
315 Self::new_owned(None)
316 }
317}
318
319impl BufferFormatter for BinaryFormatter {
320 #[inline]
321 fn get_separator(&self) -> &str {
322 self.separator.as_str()
323 }
324
325 #[inline]
326 fn format_byte(&self, byte: &u8) -> String {
327 format!("{byte:08b}")
328 }
329}
330
331impl BufferFormatter for Box<BinaryFormatter> {
332 #[inline]
333 fn get_separator(&self) -> &str {
334 (**self).get_separator()
335 }
336
337 #[inline]
338 fn format_byte(&self, byte: &u8) -> String {
339 (**self).format_byte(byte)
340 }
341}
342
343impl Default for BinaryFormatter {
344 fn default() -> Self {
345 Self::new_default()
346 }
347}
348
349#[cfg(test)]
354mod tests {
355 use crate::buffer_formatter::BinaryFormatter;
356 use crate::buffer_formatter::BufferFormatter;
357 use crate::buffer_formatter::DecimalFormatter;
358 use crate::buffer_formatter::LowercaseHexadecimalFormatter;
359 use crate::buffer_formatter::OctalFormatter;
360 use crate::buffer_formatter::UppercaseHexadecimalFormatter;
361
362 const FORMATTING_TEST_VALUES: &[u8] = &[10, 11, 12, 13, 14, 15, 16, 17, 18];
363
364 #[test]
365 fn test_buffer_formatting() {
366 let lowercase_hexadecimal = LowercaseHexadecimalFormatter::new_default();
367 let uppercase_hexadecimal = UppercaseHexadecimalFormatter::new_default();
368 let decimal = DecimalFormatter::new_default();
369 let octal = OctalFormatter::new_default();
370 let binary = BinaryFormatter::new_default();
371
372 assert_eq!(
373 lowercase_hexadecimal.format_buffer(FORMATTING_TEST_VALUES),
374 String::from("0a:0b:0c:0d:0e:0f:10:11:12")
375 );
376 assert_eq!(
377 uppercase_hexadecimal.format_buffer(FORMATTING_TEST_VALUES),
378 String::from("0A:0B:0C:0D:0E:0F:10:11:12")
379 );
380 assert_eq!(
381 decimal.format_buffer(FORMATTING_TEST_VALUES),
382 String::from("10:11:12:13:14:15:16:17:18")
383 );
384 assert_eq!(
385 octal.format_buffer(FORMATTING_TEST_VALUES),
386 String::from("012:013:014:015:016:017:020:021:022")
387 );
388 assert_eq!(
389 binary.format_buffer(FORMATTING_TEST_VALUES),
390 String::from(
391 "00001010:00001011:00001100:00001101:00001110:00001111:00010000:00010001:00010010"
392 )
393 );
394 }
395
396 #[test]
397 fn test_custom_separator() {
398 let lowercase_hexadecimal = LowercaseHexadecimalFormatter::new(Some("-"));
399 let uppercase_hexadecimal = UppercaseHexadecimalFormatter::new(Some("-"));
400 let decimal = DecimalFormatter::new(Some("-"));
401 let octal = OctalFormatter::new(Some("-"));
402 let binary = BinaryFormatter::new(Some("-"));
403
404 assert_eq!(
405 lowercase_hexadecimal.format_buffer(FORMATTING_TEST_VALUES),
406 String::from("0a-0b-0c-0d-0e-0f-10-11-12")
407 );
408 assert_eq!(
409 uppercase_hexadecimal.format_buffer(FORMATTING_TEST_VALUES),
410 String::from("0A-0B-0C-0D-0E-0F-10-11-12")
411 );
412 assert_eq!(
413 decimal.format_buffer(FORMATTING_TEST_VALUES),
414 String::from("10-11-12-13-14-15-16-17-18")
415 );
416 assert_eq!(
417 octal.format_buffer(FORMATTING_TEST_VALUES),
418 String::from("012-013-014-015-016-017-020-021-022")
419 );
420 assert_eq!(
421 binary.format_buffer(FORMATTING_TEST_VALUES),
422 String::from(
423 "00001010-00001011-00001100-00001101-00001110-00001111-00010000-00010001-00010010"
424 )
425 );
426 }
427
428 fn assert_unpin<T: Unpin>() {}
429
430 #[test]
431 fn test_unpin() {
432 assert_unpin::<BinaryFormatter>();
433 assert_unpin::<DecimalFormatter>();
434 assert_unpin::<LowercaseHexadecimalFormatter>();
435 assert_unpin::<UppercaseHexadecimalFormatter>();
436 assert_unpin::<OctalFormatter>();
437 }
438
439 #[test]
440 fn test_trait_object_safety() {
441 let lowercase_hexadecimal: Box<dyn BufferFormatter> =
443 Box::new(LowercaseHexadecimalFormatter::new(None));
444 let uppercase_hexadecimal: Box<dyn BufferFormatter> =
445 Box::new(UppercaseHexadecimalFormatter::new(None));
446 let decimal: Box<dyn BufferFormatter> = Box::new(DecimalFormatter::new(None));
447 let octal: Box<dyn BufferFormatter> = Box::new(OctalFormatter::new(None));
448 let binary: Box<dyn BufferFormatter> = Box::new(BinaryFormatter::new(None));
449
450 _ = lowercase_hexadecimal.get_separator();
452 _ = lowercase_hexadecimal.format_buffer(b"qwertyuiop");
453
454 _ = uppercase_hexadecimal.get_separator();
455 _ = uppercase_hexadecimal.format_buffer(b"qwertyuiop");
456
457 _ = decimal.get_separator();
458 _ = decimal.format_buffer(b"qwertyuiop");
459
460 _ = octal.get_separator();
461 _ = octal.format_buffer(b"qwertyuiop");
462
463 _ = binary.get_separator();
464 _ = binary.format_buffer(b"qwertyuiop");
465 }
466
467 fn assert_buffer_formatter<T: BufferFormatter>() {}
468
469 #[test]
470 fn test_box() {
471 assert_buffer_formatter::<Box<dyn BufferFormatter>>();
472 assert_buffer_formatter::<Box<LowercaseHexadecimalFormatter>>();
473 assert_buffer_formatter::<Box<UppercaseHexadecimalFormatter>>();
474 assert_buffer_formatter::<Box<DecimalFormatter>>();
475 assert_buffer_formatter::<Box<OctalFormatter>>();
476 assert_buffer_formatter::<Box<BinaryFormatter>>();
477 }
478
479 fn assert_send<T: Send>() {}
480
481 #[test]
482 fn test_send() {
483 assert_send::<LowercaseHexadecimalFormatter>();
484 assert_send::<UppercaseHexadecimalFormatter>();
485 assert_send::<DecimalFormatter>();
486 assert_send::<OctalFormatter>();
487 assert_send::<BinaryFormatter>();
488
489 assert_send::<Box<dyn BufferFormatter>>();
490 assert_send::<Box<LowercaseHexadecimalFormatter>>();
491 assert_send::<Box<UppercaseHexadecimalFormatter>>();
492 assert_send::<Box<DecimalFormatter>>();
493 assert_send::<Box<OctalFormatter>>();
494 assert_send::<Box<BinaryFormatter>>();
495 }
496}