alloy_primitives/bytes/
mod.rs1use 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#[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 #[inline]
289 pub const fn new() -> Self {
290 Self(bytes::Bytes::new())
291 }
292
293 #[inline]
307 pub const fn from_static(bytes: &'static [u8]) -> Self {
308 Self(bytes::Bytes::from_static(bytes))
309 }
310
311 #[inline]
313 pub fn copy_from_slice(data: &[u8]) -> Self {
314 Self(bytes::Bytes::copy_from_slice(data))
315 }
316
317 #[inline]
324 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
325 Self(self.0.slice(range))
326 }
327
328 #[inline]
335 pub fn slice_ref(&self, subset: &[u8]) -> Self {
336 Self(self.0.slice_ref(subset))
337 }
338
339 #[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 #[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}