alloy_primitives/bytes/
mod.rs1use crate::FixedBytes;
2use alloc::{boxed::Box, vec::Vec};
3use core::{
4 borrow::Borrow,
5 fmt,
6 ops::{Deref, DerefMut, RangeBounds},
7};
8
9#[cfg(feature = "borsh")]
10mod borsh;
11
12#[cfg(feature = "rlp")]
13mod rlp;
14
15#[cfg(feature = "rkyv")]
16mod rkyv;
17
18#[cfg(feature = "serde")]
19mod serde;
20
21#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
23#[repr(transparent)]
24pub struct Bytes(pub bytes::Bytes);
25
26impl Default for &Bytes {
27 #[inline]
28 fn default() -> Self {
29 static EMPTY: Bytes = Bytes::new();
30 &EMPTY
31 }
32}
33
34impl fmt::Debug for Bytes {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 fmt::LowerHex::fmt(self, f)
37 }
38}
39
40impl fmt::Display for Bytes {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 fmt::LowerHex::fmt(self, f)
43 }
44}
45
46impl fmt::LowerHex for Bytes {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 f.pad(&hex::encode_prefixed(self.as_ref()))
49 }
50}
51
52impl fmt::UpperHex for Bytes {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 f.pad(&hex::encode_upper_prefixed(self.as_ref()))
55 }
56}
57
58impl Deref for Bytes {
59 type Target = bytes::Bytes;
60
61 #[inline]
62 fn deref(&self) -> &Self::Target {
63 &self.0
64 }
65}
66
67impl DerefMut for Bytes {
68 #[inline]
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 &mut self.0
71 }
72}
73
74impl AsRef<[u8]> for Bytes {
75 #[inline]
76 fn as_ref(&self) -> &[u8] {
77 self.0.as_ref()
78 }
79}
80
81impl Borrow<[u8]> for Bytes {
82 #[inline]
83 fn borrow(&self) -> &[u8] {
84 self.as_ref()
85 }
86}
87
88impl FromIterator<u8> for Bytes {
89 #[inline]
90 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
91 Self(bytes::Bytes::from_iter(iter))
92 }
93}
94
95impl<'a> FromIterator<&'a u8> for Bytes {
96 #[inline]
97 fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
98 Self(iter.into_iter().copied().collect::<bytes::Bytes>())
99 }
100}
101
102impl IntoIterator for Bytes {
103 type Item = u8;
104 type IntoIter = bytes::buf::IntoIter<bytes::Bytes>;
105
106 #[inline]
107 fn into_iter(self) -> Self::IntoIter {
108 self.0.into_iter()
109 }
110}
111
112impl<'a> IntoIterator for &'a Bytes {
113 type Item = &'a u8;
114 type IntoIter = core::slice::Iter<'a, u8>;
115
116 #[inline]
117 fn into_iter(self) -> Self::IntoIter {
118 self.iter()
119 }
120}
121
122impl From<bytes::Bytes> for Bytes {
123 #[inline]
124 fn from(value: bytes::Bytes) -> Self {
125 Self(value)
126 }
127}
128
129impl From<Bytes> for bytes::Bytes {
130 #[inline]
131 fn from(value: Bytes) -> Self {
132 value.0
133 }
134}
135
136impl From<Vec<u8>> for Bytes {
137 #[inline]
138 fn from(value: Vec<u8>) -> Self {
139 Self(value.into())
140 }
141}
142
143impl<const N: usize> From<FixedBytes<N>> for Bytes {
144 #[inline]
145 fn from(value: FixedBytes<N>) -> Self {
146 value.to_vec().into()
147 }
148}
149
150impl<const N: usize> From<&'static FixedBytes<N>> for Bytes {
151 #[inline]
152 fn from(value: &'static FixedBytes<N>) -> Self {
153 Self::from_static(value.as_slice())
154 }
155}
156
157impl<const N: usize> From<[u8; N]> for Bytes {
158 #[inline]
159 fn from(value: [u8; N]) -> Self {
160 value.to_vec().into()
161 }
162}
163
164impl<const N: usize> From<&'static [u8; N]> for Bytes {
165 #[inline]
166 fn from(value: &'static [u8; N]) -> Self {
167 Self::from_static(value)
168 }
169}
170
171impl From<&'static [u8]> for Bytes {
172 #[inline]
173 fn from(value: &'static [u8]) -> Self {
174 Self::from_static(value)
175 }
176}
177
178impl From<&'static str> for Bytes {
179 #[inline]
180 fn from(value: &'static str) -> Self {
181 Self::from_static(value.as_bytes())
182 }
183}
184
185impl From<Box<[u8]>> for Bytes {
186 #[inline]
187 fn from(value: Box<[u8]>) -> Self {
188 Self(value.into())
189 }
190}
191
192impl From<Bytes> for Vec<u8> {
193 #[inline]
194 fn from(value: Bytes) -> Self {
195 value.0.into()
196 }
197}
198
199impl PartialEq<[u8]> for Bytes {
200 #[inline]
201 fn eq(&self, other: &[u8]) -> bool {
202 self[..] == *other
203 }
204}
205
206impl PartialEq<Bytes> for [u8] {
207 #[inline]
208 fn eq(&self, other: &Bytes) -> bool {
209 *self == other[..]
210 }
211}
212
213impl PartialEq<Vec<u8>> for Bytes {
214 #[inline]
215 fn eq(&self, other: &Vec<u8>) -> bool {
216 self[..] == other[..]
217 }
218}
219
220impl PartialEq<Bytes> for Vec<u8> {
221 #[inline]
222 fn eq(&self, other: &Bytes) -> bool {
223 *other == *self
224 }
225}
226
227impl PartialEq<bytes::Bytes> for Bytes {
228 #[inline]
229 fn eq(&self, other: &bytes::Bytes) -> bool {
230 other == self.as_ref()
231 }
232}
233
234impl core::str::FromStr for Bytes {
235 type Err = hex::FromHexError;
236
237 #[inline]
238 fn from_str(value: &str) -> Result<Self, Self::Err> {
239 hex::decode(value).map(Into::into)
240 }
241}
242
243impl hex::FromHex for Bytes {
244 type Error = hex::FromHexError;
245
246 #[inline]
247 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
248 hex::decode(hex).map(Self::from)
249 }
250}
251
252impl bytes::Buf for Bytes {
253 #[inline]
254 fn remaining(&self) -> usize {
255 self.0.len()
256 }
257
258 #[inline]
259 fn chunk(&self) -> &[u8] {
260 self.0.chunk()
261 }
262
263 #[inline]
264 fn advance(&mut self, cnt: usize) {
265 self.0.advance(cnt)
266 }
267
268 #[inline]
269 fn copy_to_bytes(&mut self, len: usize) -> bytes::Bytes {
270 self.0.copy_to_bytes(len)
271 }
272}
273
274impl Bytes {
275 #[inline]
288 pub const fn new() -> Self {
289 Self(bytes::Bytes::new())
290 }
291
292 #[inline]
306 pub const fn from_static(bytes: &'static [u8]) -> Self {
307 Self(bytes::Bytes::from_static(bytes))
308 }
309
310 #[inline]
312 pub fn copy_from_slice(data: &[u8]) -> Self {
313 Self(bytes::Bytes::copy_from_slice(data))
314 }
315
316 #[inline]
323 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
324 Self(self.0.slice(range))
325 }
326
327 #[inline]
334 pub fn slice_ref(&self, subset: &[u8]) -> Self {
335 Self(self.0.slice_ref(subset))
336 }
337
338 #[must_use = "consider Bytes::truncate if you don't need the other half"]
344 #[inline]
345 pub fn split_off(&mut self, at: usize) -> Self {
346 Self(self.0.split_off(at))
347 }
348
349 #[must_use = "consider Bytes::advance if you don't need the other half"]
355 #[inline]
356 pub fn split_to(&mut self, at: usize) -> Self {
357 Self(self.0.split_to(at))
358 }
359}
360
361#[cfg(feature = "arbitrary")]
362impl<'a> arbitrary::Arbitrary<'a> for Bytes {
363 #[inline]
364 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
365 u.arbitrary_iter()?.collect::<arbitrary::Result<Vec<u8>>>().map(Into::into)
366 }
367
368 #[inline]
369 fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
370 Ok(Self(u.take_rest().to_vec().into()))
371 }
372
373 #[inline]
374 fn size_hint(_depth: usize) -> (usize, Option<usize>) {
375 (0, None)
376 }
377}
378
379#[cfg(feature = "arbitrary")]
380impl proptest::arbitrary::Arbitrary for Bytes {
381 type Parameters = proptest::arbitrary::ParamsFor<Vec<u8>>;
382 type Strategy = proptest::arbitrary::Mapped<Vec<u8>, Self>;
383
384 #[inline]
385 fn arbitrary() -> Self::Strategy {
386 use proptest::strategy::Strategy;
387 proptest::arbitrary::any::<Vec<u8>>().prop_map(|vec| Self(vec.into()))
388 }
389
390 #[inline]
391 fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
392 use proptest::strategy::Strategy;
393 proptest::arbitrary::any_with::<Vec<u8>>(args).prop_map(|vec| Self(vec.into()))
394 }
395}
396
397#[cfg(test)]
398mod tests {
399 use super::*;
400
401 #[test]
402 fn parse() {
403 let expected = Bytes::from_static(&[0x12, 0x13, 0xab, 0xcd]);
404 assert_eq!("1213abcd".parse::<Bytes>().unwrap(), expected);
405 assert_eq!("0x1213abcd".parse::<Bytes>().unwrap(), expected);
406 assert_eq!("1213ABCD".parse::<Bytes>().unwrap(), expected);
407 assert_eq!("0x1213ABCD".parse::<Bytes>().unwrap(), expected);
408 }
409
410 #[test]
411 fn format() {
412 let b = Bytes::from_static(&[1, 35, 69, 103, 137, 171, 205, 239]);
413 assert_eq!(format!("{b}"), "0x0123456789abcdef");
414 assert_eq!(format!("{b:x}"), "0x0123456789abcdef");
415 assert_eq!(format!("{b:?}"), "0x0123456789abcdef");
416 assert_eq!(format!("{b:#?}"), "0x0123456789abcdef");
417 assert_eq!(format!("{b:#x}"), "0x0123456789abcdef");
418 assert_eq!(format!("{b:X}"), "0x0123456789ABCDEF");
419 assert_eq!(format!("{b:#X}"), "0x0123456789ABCDEF");
420 }
421}