1use crate::{
4 decode::{Decode, DecodeError, Decoder},
5 encode::{Encode, Encoder, Size},
6 encode_packed::EncodePacked,
7 fmt::Hex,
8 log::{FromTopic, ToTopic, TopicHash},
9 primitive::{Primitive, Word},
10};
11use ethprim::Hasher;
12use std::{
13 borrow::{Borrow, Cow},
14 fmt::{self, Debug, Formatter},
15 mem,
16 ops::{Deref, DerefMut},
17};
18
19#[derive(Clone, Copy, Default, Eq, PartialEq)]
21#[repr(transparent)]
22pub struct Bytes<T>(pub T)
23where
24 T: ?Sized;
25
26impl Bytes<[u8]> {
27 #[allow(clippy::needless_lifetimes)]
29 pub const fn new<'a>(bytes: &'a [u8]) -> &'a Bytes<[u8]> {
30 unsafe { mem::transmute(bytes) }
36 }
37
38 #[allow(clippy::needless_lifetimes)]
40 pub const fn borrowed<'a>(bytes: &'a [u8]) -> Cow<'a, Bytes<[u8]>> {
41 Cow::Borrowed(Self::new(bytes))
42 }
43}
44
45impl<T> Bytes<T>
46where
47 T: AsRef<[u8]> + ?Sized,
48{
49 pub fn as_bytes(&self) -> &[u8] {
51 self.as_ref()
52 }
53}
54
55impl<T> Bytes<T>
56where
57 T: AsMut<[u8]> + ?Sized,
58{
59 pub fn as_bytes_mut(&mut self) -> &[u8] {
61 self.as_mut()
62 }
63}
64
65impl Bytes<Vec<u8>> {
66 pub fn as_borrowed(&self) -> &Bytes<[u8]> {
68 Bytes::new(&self[..])
69 }
70}
71
72impl<T> AsRef<[u8]> for Bytes<T>
73where
74 T: AsRef<[u8]> + ?Sized,
75{
76 fn as_ref(&self) -> &[u8] {
77 self.0.as_ref()
78 }
79}
80
81impl<T> AsMut<[u8]> for Bytes<T>
82where
83 T: AsMut<[u8]> + ?Sized,
84{
85 fn as_mut(&mut self) -> &mut [u8] {
86 self.0.as_mut()
87 }
88}
89
90impl<T> Debug for Bytes<T>
91where
92 T: AsRef<[u8]> + ?Sized,
93{
94 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
95 f.debug_tuple("Bytes").field(&Hex(self.0.as_ref())).finish()
96 }
97}
98
99impl<T> Deref for Bytes<T>
100where
101 T: ?Sized,
102{
103 type Target = T;
104
105 fn deref(&self) -> &Self::Target {
106 &self.0
107 }
108}
109
110impl<T> DerefMut for Bytes<T>
111where
112 T: ?Sized,
113{
114 fn deref_mut(&mut self) -> &mut Self::Target {
115 &mut self.0
116 }
117}
118
119impl Borrow<Bytes<[u8]>> for Bytes<Vec<u8>> {
120 fn borrow(&self) -> &Bytes<[u8]> {
121 self.as_borrowed()
122 }
123}
124
125impl ToOwned for Bytes<[u8]> {
126 type Owned = Bytes<Vec<u8>>;
127
128 fn to_owned(&self) -> Self::Owned {
129 Bytes(self.0.to_owned())
130 }
131}
132
133macro_rules! impl_fixed_bytes {
134 ($($n:literal,)*) => {$(
135 impl Primitive for Bytes<[u8; $n]> {
136 fn to_word(&self) -> Word {
137 let mut word = Word::default();
138 word[..$n].copy_from_slice(self.as_ref());
139 word
140 }
141
142 fn from_word(word: Word) -> Option<Self> {
143 if word[$n..] != [0; 32 - $n] {
144 return None;
145 }
146 let mut bytes = Self::default();
147 bytes.copy_from_slice(&word[..$n]);
148 Some(bytes)
149 }
150 }
151
152 impl EncodePacked for Bytes<[u8; $n]> {
153 fn packed_size(&self) -> usize {
154 $n
155 }
156
157 fn encode_packed(&self, out: &mut [u8]) {
158 out.copy_from_slice(self.as_ref())
159 }
160 }
161 )*};
162}
163
164impl_fixed_bytes! {
165 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
166 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
167}
168
169impl Encode for Bytes<[u8]> {
170 fn size(&self) -> Size {
171 Bytes(&self.0).size()
172 }
173
174 fn encode(&self, encoder: &mut Encoder) {
175 Bytes(&self.0).encode(encoder)
176 }
177}
178
179impl EncodePacked for Bytes<[u8]> {
180 fn packed_size(&self) -> usize {
181 Bytes(&self.0).packed_size()
182 }
183
184 fn encode_packed(&self, out: &mut [u8]) {
185 Bytes(&self.0).encode_packed(out)
186 }
187}
188
189impl ToTopic for Bytes<[u8]> {
190 fn to_topic(&self) -> Word {
191 Bytes(&self.0).to_topic()
192 }
193}
194
195impl TopicHash for Bytes<[u8]> {
196 fn update_hash(&self, hasher: &mut Hasher) {
197 Bytes(&self.0).update_hash(hasher);
198 }
199}
200
201impl Encode for Bytes<&'_ [u8]> {
202 fn size(&self) -> Size {
203 let words = self.len().div_ceil(32);
204 Size::Dynamic(1 + words, 0)
205 }
206
207 fn encode(&self, encoder: &mut Encoder) {
208 encoder.write(&self.len());
209 encoder.write_bytes(self);
210 }
211}
212
213impl EncodePacked for Bytes<&'_ [u8]> {
214 fn packed_size(&self) -> usize {
215 self.len()
216 }
217
218 fn encode_packed(&self, out: &mut [u8]) {
219 out.copy_from_slice(self);
220 }
221}
222
223impl ToTopic for Bytes<&'_ [u8]> {
224 fn to_topic(&self) -> Word {
225 let mut hasher = Hasher::new();
226 hasher.update(self);
227 *hasher.finalize()
228 }
229}
230
231impl TopicHash for Bytes<&'_ [u8]> {
232 fn update_hash(&self, hasher: &mut Hasher) {
233 hasher.update(self);
234
235 static ZEROS: Word = [0; 32];
236 let padding = (32 - (self.len() % 32)) % 32;
237 hasher.update(&ZEROS[..padding]);
238 }
239}
240
241impl Encode for Bytes<Vec<u8>> {
242 fn size(&self) -> Size {
243 Bytes(&self[..]).size()
244 }
245
246 fn encode(&self, encoder: &mut Encoder) {
247 Bytes(&self[..]).encode(encoder)
248 }
249}
250
251impl EncodePacked for Bytes<Vec<u8>> {
252 fn packed_size(&self) -> usize {
253 Bytes(&self[..]).packed_size()
254 }
255
256 fn encode_packed(&self, out: &mut [u8]) {
257 Bytes(&self[..]).encode_packed(out)
258 }
259}
260
261impl Decode for Bytes<Vec<u8>> {
262 fn is_dynamic() -> bool {
263 true
264 }
265
266 fn decode(decoder: &mut Decoder) -> Result<Self, DecodeError> {
267 let len = decoder.read_size()?;
268 Ok(Self(decoder.read_bytes(len)?.to_owned()))
269 }
270}
271
272impl ToTopic for Bytes<Vec<u8>> {
273 fn to_topic(&self) -> Word {
274 Bytes(&self[..]).to_topic()
275 }
276}
277
278impl FromTopic for Bytes<Vec<u8>> {
279 fn from_topic(_: Word) -> Option<Self> {
280 Some(Self::default())
281 }
282}
283
284impl TopicHash for Bytes<Vec<u8>> {
285 fn update_hash(&self, hasher: &mut Hasher) {
286 Bytes(&self[..]).update_hash(hasher);
287 }
288}