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 = "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<Bytes> for Vec<u8> {
187    #[inline]
188    fn from(value: Bytes) -> Self {
189        value.0.into()
190    }
191}
192
193impl PartialEq<[u8]> for Bytes {
194    #[inline]
195    fn eq(&self, other: &[u8]) -> bool {
196        self[..] == *other
197    }
198}
199
200impl PartialEq<Bytes> for [u8] {
201    #[inline]
202    fn eq(&self, other: &Bytes) -> bool {
203        *self == other[..]
204    }
205}
206
207impl PartialEq<Vec<u8>> for Bytes {
208    #[inline]
209    fn eq(&self, other: &Vec<u8>) -> bool {
210        self[..] == other[..]
211    }
212}
213
214impl PartialEq<Bytes> for Vec<u8> {
215    #[inline]
216    fn eq(&self, other: &Bytes) -> bool {
217        *other == *self
218    }
219}
220
221impl PartialEq<bytes::Bytes> for Bytes {
222    #[inline]
223    fn eq(&self, other: &bytes::Bytes) -> bool {
224        other == self.as_ref()
225    }
226}
227
228impl core::str::FromStr for Bytes {
229    type Err = hex::FromHexError;
230
231    #[inline]
232    fn from_str(value: &str) -> Result<Self, Self::Err> {
233        hex::decode(value).map(Into::into)
234    }
235}
236
237impl hex::FromHex for Bytes {
238    type Error = hex::FromHexError;
239
240    #[inline]
241    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
242        hex::decode(hex).map(Self::from)
243    }
244}
245
246impl bytes::Buf for Bytes {
247    #[inline]
248    fn remaining(&self) -> usize {
249        self.0.len()
250    }
251
252    #[inline]
253    fn chunk(&self) -> &[u8] {
254        self.0.chunk()
255    }
256
257    #[inline]
258    fn advance(&mut self, cnt: usize) {
259        self.0.advance(cnt)
260    }
261
262    #[inline]
263    fn copy_to_bytes(&mut self, len: usize) -> bytes::Bytes {
264        self.0.copy_to_bytes(len)
265    }
266}
267
268impl Bytes {
269    /// Creates a new empty `Bytes`.
270    ///
271    /// This will not allocate and the returned `Bytes` handle will be empty.
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// use alloy_primitives::Bytes;
277    ///
278    /// let b = Bytes::new();
279    /// assert_eq!(&b[..], b"");
280    /// ```
281    #[inline]
282    pub const fn new() -> Self {
283        Self(bytes::Bytes::new())
284    }
285
286    /// Creates a new `Bytes` from a static slice.
287    ///
288    /// The returned `Bytes` will point directly to the static slice. There is
289    /// no allocating or copying.
290    ///
291    /// # Examples
292    ///
293    /// ```
294    /// use alloy_primitives::Bytes;
295    ///
296    /// let b = Bytes::from_static(b"hello");
297    /// assert_eq!(&b[..], b"hello");
298    /// ```
299    #[inline]
300    pub const fn from_static(bytes: &'static [u8]) -> Self {
301        Self(bytes::Bytes::from_static(bytes))
302    }
303
304    /// Creates a new `Bytes` instance from a slice by copying it.
305    #[inline]
306    pub fn copy_from_slice(data: &[u8]) -> Self {
307        Self(bytes::Bytes::copy_from_slice(data))
308    }
309
310    /// Returns a slice of self for the provided range.
311    ///
312    /// # Panics
313    ///
314    /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
315    /// will panic.
316    #[inline]
317    pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
318        Self(self.0.slice(range))
319    }
320
321    /// Returns a slice of self that is equivalent to the given `subset`.
322    ///
323    /// # Panics
324    ///
325    /// Requires that the given `subset` slice is in fact contained within the
326    /// `Bytes` buffer; otherwise this function will panic.
327    #[inline]
328    pub fn slice_ref(&self, subset: &[u8]) -> Self {
329        Self(self.0.slice_ref(subset))
330    }
331
332    /// Splits the bytes into two at the given index.
333    ///
334    /// # Panics
335    ///
336    /// Panics if `at > len`.
337    #[must_use = "consider Bytes::truncate if you don't need the other half"]
338    #[inline]
339    pub fn split_off(&mut self, at: usize) -> Self {
340        Self(self.0.split_off(at))
341    }
342
343    /// Splits the bytes into two at the given index.
344    ///
345    /// # Panics
346    ///
347    /// Panics if `at > len`.
348    #[must_use = "consider Bytes::advance if you don't need the other half"]
349    #[inline]
350    pub fn split_to(&mut self, at: usize) -> Self {
351        Self(self.0.split_to(at))
352    }
353}
354
355#[cfg(feature = "arbitrary")]
356impl<'a> arbitrary::Arbitrary<'a> for Bytes {
357    #[inline]
358    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
359        u.arbitrary_iter()?.collect::<arbitrary::Result<Vec<u8>>>().map(Into::into)
360    }
361
362    #[inline]
363    fn arbitrary_take_rest(u: arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
364        Ok(Self(u.take_rest().to_vec().into()))
365    }
366
367    #[inline]
368    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
369        (0, None)
370    }
371}
372
373#[cfg(feature = "arbitrary")]
374impl proptest::arbitrary::Arbitrary for Bytes {
375    type Parameters = proptest::arbitrary::ParamsFor<Vec<u8>>;
376    type Strategy = proptest::arbitrary::Mapped<Vec<u8>, Self>;
377
378    #[inline]
379    fn arbitrary() -> Self::Strategy {
380        use proptest::strategy::Strategy;
381        proptest::arbitrary::any::<Vec<u8>>().prop_map(|vec| Self(vec.into()))
382    }
383
384    #[inline]
385    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
386        use proptest::strategy::Strategy;
387        proptest::arbitrary::any_with::<Vec<u8>>(args).prop_map(|vec| Self(vec.into()))
388    }
389}
390
391#[cfg(test)]
392mod tests {
393    use super::*;
394
395    #[test]
396    fn parse() {
397        let expected = Bytes::from_static(&[0x12, 0x13, 0xab, 0xcd]);
398        assert_eq!("1213abcd".parse::<Bytes>().unwrap(), expected);
399        assert_eq!("0x1213abcd".parse::<Bytes>().unwrap(), expected);
400        assert_eq!("1213ABCD".parse::<Bytes>().unwrap(), expected);
401        assert_eq!("0x1213ABCD".parse::<Bytes>().unwrap(), expected);
402    }
403
404    #[test]
405    fn format() {
406        let b = Bytes::from_static(&[1, 35, 69, 103, 137, 171, 205, 239]);
407        assert_eq!(format!("{b}"), "0x0123456789abcdef");
408        assert_eq!(format!("{b:x}"), "0x0123456789abcdef");
409        assert_eq!(format!("{b:?}"), "0x0123456789abcdef");
410        assert_eq!(format!("{b:#?}"), "0x0123456789abcdef");
411        assert_eq!(format!("{b:#x}"), "0x0123456789abcdef");
412        assert_eq!(format!("{b:X}"), "0x0123456789ABCDEF");
413        assert_eq!(format!("{b:#X}"), "0x0123456789ABCDEF");
414    }
415}
OSZAR »