ethers_core/types/
bytes.rs

1use open_fastrlp::{Decodable, Encodable};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::{
4    borrow::Borrow,
5    clone::Clone,
6    fmt::{Debug, Display, Formatter, LowerHex, Result as FmtResult},
7    ops::Deref,
8    str::FromStr,
9};
10use thiserror::Error;
11
12/// Wrapper type around Bytes to deserialize/serialize "0x" prefixed ethereum hex strings
13#[derive(Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize, Ord, PartialOrd)]
14pub struct Bytes(
15    #[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
16    pub  bytes::Bytes,
17);
18
19impl hex::FromHex for Bytes {
20    type Error = hex::FromHexError;
21
22    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
23        hex::decode(hex).map(Into::into)
24    }
25}
26
27impl FromIterator<u8> for Bytes {
28    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
29        iter.into_iter().collect::<bytes::Bytes>().into()
30    }
31}
32
33impl<'a> FromIterator<&'a u8> for Bytes {
34    fn from_iter<T: IntoIterator<Item = &'a u8>>(iter: T) -> Self {
35        iter.into_iter().copied().collect::<bytes::Bytes>().into()
36    }
37}
38
39impl Bytes {
40    /// Creates a new empty `Bytes`.
41    ///
42    /// This will not allocate and the returned `Bytes` handle will be empty.
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// use ethers_core::types::Bytes;
48    ///
49    /// let b = Bytes::new();
50    /// assert_eq!(&b[..], b"");
51    /// ```
52    #[inline]
53    pub const fn new() -> Self {
54        Self(bytes::Bytes::new())
55    }
56
57    /// Creates a new `Bytes` from a static slice.
58    ///
59    /// The returned `Bytes` will point directly to the static slice. There is
60    /// no allocating or copying.
61    ///
62    /// # Examples
63    ///
64    /// ```
65    /// use ethers_core::types::Bytes;
66    ///
67    /// let b = Bytes::from_static(b"hello");
68    /// assert_eq!(&b[..], b"hello");
69    /// ```
70    #[inline]
71    pub const fn from_static(bytes: &'static [u8]) -> Self {
72        Self(bytes::Bytes::from_static(bytes))
73    }
74
75    fn hex_encode(&self) -> String {
76        hex::encode(self.0.as_ref())
77    }
78}
79
80impl Debug for Bytes {
81    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
82        write!(f, "Bytes(0x{})", self.hex_encode())
83    }
84}
85
86impl Display for Bytes {
87    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
88        write!(f, "0x{}", self.hex_encode())
89    }
90}
91
92impl LowerHex for Bytes {
93    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
94        write!(f, "0x{}", self.hex_encode())
95    }
96}
97
98impl Deref for Bytes {
99    type Target = [u8];
100
101    #[inline]
102    fn deref(&self) -> &[u8] {
103        self.as_ref()
104    }
105}
106
107impl AsRef<[u8]> for Bytes {
108    fn as_ref(&self) -> &[u8] {
109        self.0.as_ref()
110    }
111}
112
113impl Borrow<[u8]> for Bytes {
114    fn borrow(&self) -> &[u8] {
115        self.as_ref()
116    }
117}
118
119impl IntoIterator for Bytes {
120    type Item = u8;
121    type IntoIter = bytes::buf::IntoIter<bytes::Bytes>;
122
123    fn into_iter(self) -> Self::IntoIter {
124        self.0.into_iter()
125    }
126}
127
128impl<'a> IntoIterator for &'a Bytes {
129    type Item = &'a u8;
130    type IntoIter = core::slice::Iter<'a, u8>;
131
132    fn into_iter(self) -> Self::IntoIter {
133        self.as_ref().iter()
134    }
135}
136
137impl From<bytes::Bytes> for Bytes {
138    fn from(src: bytes::Bytes) -> Self {
139        Self(src)
140    }
141}
142
143impl From<Vec<u8>> for Bytes {
144    fn from(src: Vec<u8>) -> Self {
145        Self(src.into())
146    }
147}
148
149impl<const N: usize> From<[u8; N]> for Bytes {
150    fn from(src: [u8; N]) -> Self {
151        src.to_vec().into()
152    }
153}
154
155impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
156    fn from(src: &'a [u8; N]) -> Self {
157        src.to_vec().into()
158    }
159}
160
161impl PartialEq<[u8]> for Bytes {
162    fn eq(&self, other: &[u8]) -> bool {
163        self.as_ref() == other
164    }
165}
166
167impl PartialEq<Bytes> for [u8] {
168    fn eq(&self, other: &Bytes) -> bool {
169        *other == *self
170    }
171}
172
173impl PartialEq<Vec<u8>> for Bytes {
174    fn eq(&self, other: &Vec<u8>) -> bool {
175        self.as_ref() == &other[..]
176    }
177}
178
179impl PartialEq<Bytes> for Vec<u8> {
180    fn eq(&self, other: &Bytes) -> bool {
181        *other == *self
182    }
183}
184
185impl PartialEq<bytes::Bytes> for Bytes {
186    fn eq(&self, other: &bytes::Bytes) -> bool {
187        other == self.as_ref()
188    }
189}
190
191impl Encodable for Bytes {
192    fn length(&self) -> usize {
193        self.0.length()
194    }
195    fn encode(&self, out: &mut dyn bytes::BufMut) {
196        self.0.encode(out)
197    }
198}
199
200impl Decodable for Bytes {
201    fn decode(buf: &mut &[u8]) -> Result<Self, open_fastrlp::DecodeError> {
202        Ok(Self(bytes::Bytes::decode(buf)?))
203    }
204}
205
206#[derive(Debug, Clone, Error)]
207#[error("Failed to parse bytes: {0}")]
208pub struct ParseBytesError(hex::FromHexError);
209
210impl FromStr for Bytes {
211    type Err = ParseBytesError;
212
213    fn from_str(value: &str) -> Result<Self, Self::Err> {
214        hex::FromHex::from_hex(value).map_err(ParseBytesError)
215    }
216}
217
218pub fn serialize_bytes<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
219where
220    S: Serializer,
221    T: AsRef<[u8]>,
222{
223    s.serialize_str(&hex::encode_prefixed(x))
224}
225
226pub fn deserialize_bytes<'de, D>(d: D) -> Result<bytes::Bytes, D::Error>
227where
228    D: Deserializer<'de>,
229{
230    let value = String::deserialize(d)?;
231    hex::decode(value).map(Into::into).map_err(serde::de::Error::custom)
232}
233
234#[cfg(test)]
235mod tests {
236    use super::*;
237
238    #[test]
239    fn hex_formatting() {
240        let b = Bytes::from(vec![1, 35, 69, 103, 137, 171, 205, 239]);
241        let expected = String::from("0x0123456789abcdef");
242        assert_eq!(format!("{b:x}"), expected);
243        assert_eq!(format!("{b}"), expected);
244    }
245
246    #[test]
247    fn test_from_str() {
248        let b = Bytes::from_str("0x1213");
249        assert!(b.is_ok());
250        let b = b.unwrap();
251        assert_eq!(b.as_ref(), hex::decode("1213").unwrap());
252
253        let b = Bytes::from_str("1213");
254        let b = b.unwrap();
255        assert_eq!(b.as_ref(), hex::decode("1213").unwrap());
256    }
257
258    #[test]
259    fn test_debug_formatting() {
260        let b = Bytes::from(vec![1, 35, 69, 103, 137, 171, 205, 239]);
261        assert_eq!(format!("{b:?}"), "Bytes(0x0123456789abcdef)");
262        assert_eq!(format!("{b:#?}"), "Bytes(0x0123456789abcdef)");
263    }
264}