xash3d_protocol/
wrappers.rs

1// SPDX-License-Identifier: LGPL-3.0-only
2// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
3
4//! Wrappers for byte slices with pretty-printers.
5
6use std::fmt;
7use std::ops::Deref;
8
9use crate::cursor::{CursorMut, PutKeyValue};
10use crate::CursorError;
11
12/// Wrapper for slice of bytes with printing the bytes as a string.
13///
14/// # Examples
15///
16/// ```rust
17/// # use xash3d_protocol::wrappers::Str;
18/// let s = format!("{}", Str(b"\xff\talex\n"));
19/// assert_eq!(s, "\\xff\\talex\\n");
20/// ```
21#[derive(Copy, Clone, PartialEq, Eq, Default)]
22pub struct Str<T>(pub T);
23
24impl<T> From<T> for Str<T> {
25    fn from(value: T) -> Self {
26        Self(value)
27    }
28}
29
30impl PutKeyValue for Str<&[u8]> {
31    fn put_key_value<'a, 'b>(
32        &self,
33        cur: &'b mut CursorMut<'a>,
34    ) -> Result<&'b mut CursorMut<'a>, CursorError> {
35        cur.put_bytes(self.0)
36    }
37}
38
39impl<T> fmt::Debug for Str<T>
40where
41    T: AsRef<[u8]>,
42{
43    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
44        write!(fmt, "\"{}\"", self)
45    }
46}
47
48impl<T> fmt::Display for Str<T>
49where
50    T: AsRef<[u8]>,
51{
52    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
53        for &c in self.0.as_ref() {
54            match c {
55                b'\n' => write!(fmt, "\\n")?,
56                b'\t' => write!(fmt, "\\t")?,
57                b'\\' => write!(fmt, "\\\\")?,
58                _ if c.is_ascii_graphic() || c == b' ' => {
59                    write!(fmt, "{}", c as char)?;
60                }
61                _ => write!(fmt, "\\x{:02x}", c)?,
62            }
63        }
64        Ok(())
65    }
66}
67
68impl<T> Deref for Str<T> {
69    type Target = T;
70
71    fn deref(&self) -> &Self::Target {
72        &self.0
73    }
74}
75
76/// Wrapper for slice of bytes without printing.
77///
78/// # Examples
79///
80/// ```rust
81/// # use xash3d_protocol::wrappers::Hide;
82/// let s = format!("{}", Hide([1, 2, 3, 4]));
83/// assert_eq!(s, "<hidden>");
84/// ```
85#[derive(Copy, Clone, PartialEq, Eq, Default)]
86pub struct Hide<T>(pub T);
87
88impl<T> fmt::Debug for Hide<T> {
89    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
90        write!(fmt, "<hidden>")
91    }
92}
93
94impl<T> fmt::Display for Hide<T> {
95    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
96        write!(fmt, "<hidden>")
97    }
98}
99
100impl<T> Deref for Hide<T> {
101    type Target = T;
102
103    fn deref(&self) -> &Self::Target {
104        &self.0
105    }
106}