alloy_primitives/bytes/
mod.rs

1use 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/// Wrapper type around [`bytes::Bytes`] to support "0x" prefixed hex strings.
22#[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    /// Creates a new empty `Bytes`.
276    ///
277    /// This will not allocate and the returned `Bytes` handle will be empty.
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// use alloy_primitives::Bytes;
283    ///
284    /// let b = Bytes::new();
285    /// assert_eq!(&b[..], b"");
286    /// ```
287    #[inline]
288    pub const fn new() -> Self {
289        Self(bytes::Bytes::new())
290    }
291
292    /// Creates a new `Bytes` from a static slice.
293    ///
294    /// The returned `Bytes` will point directly to the static slice. There is
295    /// no allocating or copying.
296    ///
297    /// # Examples
298    ///
299    /// ```
300    /// use alloy_primitives::Bytes;
301    ///
302    /// let b = Bytes::from_static(b"hello");
303    /// assert_eq!(&b[..], b"hello");
304    /// ```
305    #[inline]
306    pub const fn from_static(bytes: &'static [u8]) -> Self {
307        Self(bytes::Bytes::from_static(bytes))
308    }
309
310    /// Creates a new `Bytes` instance from a slice by copying it.
311    #[inline]
312    pub fn copy_from_slice(data: &[u8]) -> Self {
313        Self(bytes::Bytes::copy_from_slice(data))
314    }
315
316    /// Returns a slice of self for the provided range.
317    ///
318    /// # Panics
319    ///
320    /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
321    /// will panic.
322    #[inline]
323    pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
324        Self(self.0.slice(range))
325    }
326
327    /// Returns a slice of self that is equivalent to the given `subset`.
328    ///
329    /// # Panics
330    ///
331    /// Requires that the given `subset` slice is in fact contained within the
332    /// `Bytes` buffer; otherwise this function will panic.
333    #[inline]
334    pub fn slice_ref(&self, subset: &[u8]) -> Self {
335        Self(self.0.slice_ref(subset))
336    }
337
338    /// Splits the bytes into two at the given index.
339    ///
340    /// # Panics
341    ///
342    /// Panics if `at > len`.
343    #[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    /// Splits the bytes into two at the given index.
350    ///
351    /// # Panics
352    ///
353    /// Panics if `at > len`.
354    #[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}