alloy_primitives/bytes/
mod.rs

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