librqbit_buffers/
lib.rs

1// This crate used for making working with &[u8] or Vec<u8> generic in other parts of librqbit,
2// for nicer display of binary data etc.
3//
4// Not useful outside of librqbit.
5
6use std::borrow::Borrow;
7
8use bytes::Bytes;
9use serde::{Deserialize, Deserializer, Serialize};
10
11use clone_to_owned::CloneToOwned;
12
13#[derive(Default, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
14pub struct ByteBufOwned(pub bytes::Bytes);
15
16#[derive(Default, Deserialize, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)]
17#[serde(transparent)]
18pub struct ByteBuf<'a>(pub &'a [u8]);
19
20pub trait ByteBufT:
21    AsRef<[u8]> + std::hash::Hash + Serialize + Eq + core::fmt::Debug + CloneToOwned + Borrow<[u8]>
22{
23    fn as_slice(&self) -> &[u8];
24}
25
26impl ByteBufT for ByteBufOwned {
27    fn as_slice(&self) -> &[u8] {
28        self.as_ref()
29    }
30}
31
32impl ByteBufT for ByteBuf<'_> {
33    fn as_slice(&self) -> &[u8] {
34        self.as_ref()
35    }
36}
37
38struct HexBytes<'a>(&'a [u8]);
39impl std::fmt::Display for HexBytes<'_> {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        for byte in self.0 {
42            write!(f, "{byte:02x?}")?;
43        }
44        Ok(())
45    }
46}
47
48fn debug_bytes(b: &[u8], f: &mut std::fmt::Formatter<'_>, debug_strings: bool) -> std::fmt::Result {
49    if b.is_empty() {
50        return Ok(());
51    }
52    if b.iter().all(|b| *b == 0) {
53        return write!(f, "<{} bytes, all zeroes>", b.len());
54    }
55    match std::str::from_utf8(b) {
56        Ok(s) => {
57            if debug_strings {
58                return write!(f, "{s:?}");
59            } else {
60                return write!(f, "{s}");
61            }
62        }
63        Err(_e) => {}
64    };
65
66    // up to 20 bytes, display hex
67    if b.len() <= 20 {
68        return write!(f, "<{} bytes, 0x{}>", b.len(), HexBytes(b));
69    }
70
71    write!(f, "<{} bytes>", b.len())
72}
73
74impl std::fmt::Debug for ByteBuf<'_> {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        debug_bytes(self.0, f, true)
77    }
78}
79
80impl std::fmt::Display for ByteBuf<'_> {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        debug_bytes(self.0, f, false)
83    }
84}
85
86impl std::fmt::Debug for ByteBufOwned {
87    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88        debug_bytes(&self.0, f, true)
89    }
90}
91
92impl std::fmt::Display for ByteBufOwned {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        debug_bytes(&self.0, f, false)
95    }
96}
97
98impl CloneToOwned for ByteBuf<'_> {
99    type Target = ByteBufOwned;
100
101    fn clone_to_owned(&self, within_buffer: Option<&Bytes>) -> Self::Target {
102        // Try zero-copy from the provided buffer.
103        if let Some(within_buffer) = within_buffer {
104            let haystack = within_buffer.as_ptr() as usize;
105            let haystack_end = haystack + within_buffer.len();
106            let needle = self.0.as_ptr() as usize;
107            let needle_end = needle + self.0.len();
108
109            if needle >= haystack && needle_end <= haystack_end {
110                return ByteBufOwned(within_buffer.slice_ref(self.0.as_ref()));
111            } else {
112                #[cfg(debug_assertions)]
113                panic!("bug: broken buffers! not inside within_buffer");
114            }
115        }
116
117        ByteBufOwned(Bytes::copy_from_slice(self.0))
118    }
119}
120
121impl CloneToOwned for ByteBufOwned {
122    type Target = ByteBufOwned;
123
124    fn clone_to_owned(&self, _within_buffer: Option<&Bytes>) -> Self::Target {
125        ByteBufOwned(self.0.clone())
126    }
127}
128
129impl std::convert::AsRef<[u8]> for ByteBuf<'_> {
130    fn as_ref(&self) -> &[u8] {
131        self.0
132    }
133}
134
135impl std::convert::AsRef<[u8]> for ByteBufOwned {
136    fn as_ref(&self) -> &[u8] {
137        &self.0
138    }
139}
140
141impl std::borrow::Borrow<[u8]> for ByteBufOwned {
142    fn borrow(&self) -> &[u8] {
143        &self.0
144    }
145}
146
147impl std::borrow::Borrow<[u8]> for ByteBuf<'_> {
148    fn borrow(&self) -> &[u8] {
149        self.0
150    }
151}
152
153impl std::ops::Deref for ByteBuf<'_> {
154    type Target = [u8];
155
156    fn deref(&self) -> &Self::Target {
157        self.0
158    }
159}
160
161impl std::ops::Deref for ByteBufOwned {
162    type Target = [u8];
163
164    fn deref(&self) -> &Self::Target {
165        &self.0
166    }
167}
168
169impl<'a> From<&'a [u8]> for ByteBuf<'a> {
170    fn from(b: &'a [u8]) -> Self {
171        Self(b)
172    }
173}
174
175impl<'a> From<&'a [u8]> for ByteBufOwned {
176    fn from(b: &'a [u8]) -> Self {
177        Self(b.to_owned().into())
178    }
179}
180
181impl From<Vec<u8>> for ByteBufOwned {
182    fn from(b: Vec<u8>) -> Self {
183        Self(b.into())
184    }
185}
186
187impl From<Bytes> for ByteBufOwned {
188    fn from(b: Bytes) -> Self {
189        Self(b)
190    }
191}
192
193impl serde::ser::Serialize for ByteBuf<'_> {
194    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195    where
196        S: serde::Serializer,
197    {
198        serializer.serialize_bytes(self.as_slice())
199    }
200}
201
202impl serde::ser::Serialize for ByteBufOwned {
203    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
204    where
205        S: serde::Serializer,
206    {
207        serializer.serialize_bytes(self.as_slice())
208    }
209}
210
211impl<'de> serde::de::Deserialize<'de> for ByteBufOwned {
212    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213    where
214        D: Deserializer<'de>,
215    {
216        struct Visitor;
217
218        impl serde::de::Visitor<'_> for Visitor {
219            type Value = ByteBufOwned;
220
221            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
222                formatter.write_str("byte string")
223            }
224            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
225            where
226                E: serde::de::Error,
227            {
228                Ok(v.to_owned().into())
229            }
230        }
231        deserializer.deserialize_byte_buf(Visitor {})
232    }
233}