ink_primitives/sol/
bytes.rs1use core::{
16 borrow::Borrow,
17 ops::Deref,
18};
19
20use alloy_sol_types::{
21 SolType as AlloySolType,
22 sol_data,
23};
24use ink_prelude::{
25 boxed::Box,
26 vec::Vec,
27};
28use scale::{
29 Decode,
30 Encode,
31};
32#[cfg(feature = "std")]
33use scale_info::TypeInfo;
34
35use crate::sol::{
36 Error,
37 SolDecode,
38 SolEncode,
39 SolTopicEncode,
40 SolTypeDecode,
41 SolTypeEncode,
42 encodable::{
43 DynSizeDefault,
44 FixedSizeDefault,
45 Word,
46 },
47 types::SolTokenType,
48 utils::{
49 append_non_empty_member_topic_bytes,
50 non_zero_multiple_of_32,
51 },
52};
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode)]
59#[cfg_attr(feature = "std", derive(TypeInfo))]
60#[repr(transparent)]
61pub struct FixedBytes<const N: usize>(pub [u8; N]);
62
63impl<const N: usize> FixedBytes<N> {
64 pub fn from_ref(value: &[u8; N]) -> &Self {
67 unsafe { &*value.as_ptr().cast::<Self>() }
70 }
71}
72
73impl<const N: usize> SolTypeDecode for FixedBytes<N>
75where
76 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
77{
78 type AlloyType = sol_data::FixedBytes<N>;
79
80 fn detokenize(
81 token: <Self::AlloyType as AlloySolType>::Token<'_>,
82 ) -> Result<Self, Error> {
83 Ok(Self(
88 token.0.0[..N]
89 .try_into()
90 .expect("Expected a slice of N bytes"),
91 ))
92 }
93}
94
95impl<const N: usize> SolTypeEncode for FixedBytes<N>
96where
97 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
98{
99 type AlloyType = sol_data::FixedBytes<N>;
100
101 const DEFAULT_VALUE: Self::DefaultType = FixedSizeDefault::WORD;
102
103 fn tokenize(&self) -> Self::TokenType<'_> {
104 let mut word = [0; 32];
107 word[..N].copy_from_slice(self.0.as_slice());
108 Word(word)
109 }
110}
111
112impl<const N: usize> SolTopicEncode for FixedBytes<N>
113where
114 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
115{
116 fn encode_topic<H>(&self, _: H) -> [u8; 32]
117 where
118 H: Fn(&[u8], &mut [u8; 32]),
119 {
120 self.tokenize().0
121 }
122
123 fn topic_preimage(&self, buffer: &mut Vec<u8>) {
124 buffer.extend(self.tokenize().0);
125 }
126
127 fn default_topic_preimage(buffer: &mut Vec<u8>) {
128 buffer.extend([0u8; 32]);
129 }
130
131 fn topic_preimage_size(&self) -> usize {
132 Self::default_topic_preimage_size()
133 }
134
135 fn default_topic_preimage_size() -> usize {
136 32
137 }
138}
139
140impl<const N: usize> SolTokenType for FixedBytes<N>
141where
142 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
143{
144 type TokenType<'enc> = Word;
145
146 type DefaultType = FixedSizeDefault;
147}
148
149impl<const N: usize> crate::sol::types::private::Sealed for FixedBytes<N> where
150 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes
151{
152}
153
154impl<const N: usize> SolDecode for FixedBytes<N>
156where
157 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
158{
159 type SolType = FixedBytes<N>;
160
161 fn from_sol_type(value: Self::SolType) -> Result<Self, Error> {
162 Ok(value)
163 }
164}
165
166impl<'a, const N: usize> SolEncode<'a> for FixedBytes<N>
167where
168 sol_data::ByteCount<N>: sol_data::SupportedFixedBytes,
169{
170 type SolType = &'a FixedBytes<N>;
171
172 fn to_sol_type(&'a self) -> Self::SolType {
173 self
174 }
175}
176
177impl<const N: usize> From<[u8; N]> for FixedBytes<N> {
179 fn from(value: [u8; N]) -> Self {
180 Self(value)
181 }
182}
183
184impl From<u8> for FixedBytes<1> {
185 fn from(value: u8) -> Self {
186 Self([value; 1])
187 }
188}
189
190impl<const N: usize> Deref for FixedBytes<N> {
191 type Target = [u8; N];
192
193 fn deref(&self) -> &Self::Target {
194 &self.0
195 }
196}
197
198impl<const N: usize> Borrow<[u8; N]> for FixedBytes<N> {
199 fn borrow(&self) -> &[u8; N] {
200 &self.0
201 }
202}
203
204impl<const N: usize> AsRef<[u8; N]> for FixedBytes<N> {
205 fn as_ref(&self) -> &[u8; N] {
206 &self.0
207 }
208}
209
210#[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)]
215#[cfg_attr(feature = "std", derive(TypeInfo))]
216#[repr(transparent)]
217pub struct DynBytes(pub Vec<u8>);
218
219impl DynBytes {
220 pub const fn new() -> Self {
222 Self(Vec::new())
223 }
224}
225
226impl DynBytes {
227 pub fn from_ref(value: &Vec<u8>) -> &Self {
230 unsafe { &*(value as *const Vec<u8>).cast::<Self>() }
233 }
234}
235
236impl SolTypeDecode for DynBytes {
238 type AlloyType = sol_data::Bytes;
239
240 fn detokenize(
241 token: <Self::AlloyType as AlloySolType>::Token<'_>,
242 ) -> Result<Self, Error> {
243 Ok(Self(token.into_vec()))
247 }
248}
249
250impl SolTypeEncode for DynBytes {
251 type AlloyType = sol_data::Bytes;
252
253 const DEFAULT_VALUE: Self::DefaultType = DynSizeDefault;
254
255 fn tokenize(&self) -> Self::TokenType<'_> {
256 self.0.as_slice()
257 }
258}
259
260impl SolTopicEncode for DynBytes {
261 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
262 where
263 H: Fn(&[u8], &mut [u8; 32]),
264 {
265 let mut output = [0u8; 32];
266 hasher(self.0.as_slice(), &mut output);
267 output
268 }
269
270 fn topic_preimage(&self, buffer: &mut Vec<u8>) {
271 append_non_empty_member_topic_bytes(self.0.as_slice(), buffer);
272 }
273
274 fn default_topic_preimage(buffer: &mut Vec<u8>) {
275 buffer.extend([0u8; 32]);
276 }
277
278 fn topic_preimage_size(&self) -> usize {
279 non_zero_multiple_of_32(self.0.len())
280 }
281
282 fn default_topic_preimage_size() -> usize {
283 32
284 }
285}
286
287impl SolTokenType for DynBytes {
288 type TokenType<'enc> = &'enc [u8];
289
290 type DefaultType = DynSizeDefault;
291}
292
293impl crate::sol::types::private::Sealed for DynBytes {}
294
295impl SolDecode for DynBytes {
297 type SolType = DynBytes;
298
299 fn from_sol_type(value: Self::SolType) -> Result<Self, Error> {
300 Ok(value)
301 }
302}
303
304impl<'a> SolEncode<'a> for DynBytes {
305 type SolType = &'a DynBytes;
306
307 fn to_sol_type(&'a self) -> Self::SolType {
308 self
309 }
310}
311
312impl From<Vec<u8>> for DynBytes {
314 fn from(value: Vec<u8>) -> Self {
315 Self(value)
316 }
317}
318
319impl From<Box<[u8]>> for DynBytes {
320 fn from(value: Box<[u8]>) -> Self {
321 Self(value.into_vec())
323 }
324}
325
326impl Deref for DynBytes {
327 type Target = [u8];
328
329 fn deref(&self) -> &Self::Target {
330 &self.0
331 }
332}
333
334impl Borrow<[u8]> for DynBytes {
335 fn borrow(&self) -> &[u8] {
336 &self.0
337 }
338}
339
340impl AsRef<[u8]> for DynBytes {
341 fn as_ref(&self) -> &[u8] {
342 &self.0
343 }
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Encode)]
356#[cfg_attr(feature = "std", derive(TypeInfo))]
357#[repr(transparent)]
358pub struct ByteSlice<'a>(pub &'a [u8]);
359
360impl SolTypeEncode for ByteSlice<'_> {
362 type AlloyType = sol_data::Bytes;
363
364 const DEFAULT_VALUE: Self::DefaultType = DynSizeDefault;
365
366 fn tokenize(&self) -> Self::TokenType<'_> {
367 self.0
368 }
369}
370
371impl SolTopicEncode for ByteSlice<'_> {
372 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
373 where
374 H: Fn(&[u8], &mut [u8; 32]),
375 {
376 let mut output = [0u8; 32];
377 hasher(self.0, &mut output);
378 output
379 }
380
381 fn topic_preimage(&self, buffer: &mut Vec<u8>) {
382 append_non_empty_member_topic_bytes(self.0, buffer);
383 }
384
385 fn default_topic_preimage(buffer: &mut Vec<u8>) {
386 buffer.extend([0u8; 32]);
387 }
388
389 fn topic_preimage_size(&self) -> usize {
390 non_zero_multiple_of_32(self.0.len())
391 }
392
393 fn default_topic_preimage_size() -> usize {
394 32
395 }
396}
397
398impl SolTokenType for ByteSlice<'_> {
399 type TokenType<'enc> = &'enc [u8];
400
401 type DefaultType = DynSizeDefault;
402}
403
404impl crate::sol::types::private::Sealed for ByteSlice<'_> {}
405
406impl<'a> SolEncode<'a> for ByteSlice<'a> {
408 type SolType = &'a ByteSlice<'a>;
409
410 fn to_sol_type(&'a self) -> Self::SolType {
411 self
412 }
413}
414
415impl<'a> From<&'a [u8]> for ByteSlice<'a> {
417 fn from(value: &'a [u8]) -> Self {
418 Self(value)
419 }
420}
421
422impl Deref for ByteSlice<'_> {
423 type Target = [u8];
424
425 fn deref(&self) -> &Self::Target {
426 self.0
427 }
428}
429
430impl Borrow<[u8]> for ByteSlice<'_> {
431 fn borrow(&self) -> &[u8] {
432 self.0
433 }
434}
435
436impl AsRef<[u8]> for ByteSlice<'_> {
437 fn as_ref(&self) -> &[u8] {
438 self.0
439 }
440}