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> From<FixedBytes<N>> for [u8; N] {
191 fn from(value: FixedBytes<N>) -> Self {
192 value.0
193 }
194}
195
196impl From<FixedBytes<1>> for u8 {
197 fn from(value: FixedBytes<1>) -> Self {
198 value.0[0]
199 }
200}
201
202impl<const N: usize> Deref for FixedBytes<N> {
203 type Target = [u8; N];
204
205 fn deref(&self) -> &Self::Target {
206 &self.0
207 }
208}
209
210impl<const N: usize> Borrow<[u8; N]> for FixedBytes<N> {
211 fn borrow(&self) -> &[u8; N] {
212 &self.0
213 }
214}
215
216impl<const N: usize> AsRef<[u8; N]> for FixedBytes<N> {
217 fn as_ref(&self) -> &[u8; N] {
218 &self.0
219 }
220}
221
222#[derive(Debug, Clone, PartialEq, Eq, Default, Encode, Decode)]
227#[cfg_attr(feature = "std", derive(TypeInfo))]
228#[repr(transparent)]
229pub struct DynBytes(pub Vec<u8>);
230
231impl DynBytes {
232 pub const fn new() -> Self {
234 Self(Vec::new())
235 }
236}
237
238impl DynBytes {
239 pub fn from_ref(value: &Vec<u8>) -> &Self {
242 unsafe { &*(value as *const Vec<u8>).cast::<Self>() }
245 }
246}
247
248impl SolTypeDecode for DynBytes {
250 type AlloyType = sol_data::Bytes;
251
252 fn detokenize(
253 token: <Self::AlloyType as AlloySolType>::Token<'_>,
254 ) -> Result<Self, Error> {
255 Ok(Self(token.into_vec()))
259 }
260}
261
262impl SolTypeEncode for DynBytes {
263 type AlloyType = sol_data::Bytes;
264
265 const DEFAULT_VALUE: Self::DefaultType = DynSizeDefault;
266
267 fn tokenize(&self) -> Self::TokenType<'_> {
268 self.0.as_slice()
269 }
270}
271
272impl SolTopicEncode for DynBytes {
273 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
274 where
275 H: Fn(&[u8], &mut [u8; 32]),
276 {
277 let mut output = [0u8; 32];
278 hasher(self.0.as_slice(), &mut output);
279 output
280 }
281
282 fn topic_preimage(&self, buffer: &mut Vec<u8>) {
283 append_non_empty_member_topic_bytes(self.0.as_slice(), buffer);
284 }
285
286 fn default_topic_preimage(buffer: &mut Vec<u8>) {
287 buffer.extend([0u8; 32]);
288 }
289
290 fn topic_preimage_size(&self) -> usize {
291 non_zero_multiple_of_32(self.0.len())
292 }
293
294 fn default_topic_preimage_size() -> usize {
295 32
296 }
297}
298
299impl SolTokenType for DynBytes {
300 type TokenType<'enc> = &'enc [u8];
301
302 type DefaultType = DynSizeDefault;
303}
304
305impl crate::sol::types::private::Sealed for DynBytes {}
306
307impl SolDecode for DynBytes {
309 type SolType = DynBytes;
310
311 fn from_sol_type(value: Self::SolType) -> Result<Self, Error> {
312 Ok(value)
313 }
314}
315
316impl<'a> SolEncode<'a> for DynBytes {
317 type SolType = &'a DynBytes;
318
319 fn to_sol_type(&'a self) -> Self::SolType {
320 self
321 }
322}
323
324impl From<Vec<u8>> for DynBytes {
326 fn from(value: Vec<u8>) -> Self {
327 Self(value)
328 }
329}
330
331impl From<Box<[u8]>> for DynBytes {
332 fn from(value: Box<[u8]>) -> Self {
333 Self(value.into_vec())
335 }
336}
337
338impl From<DynBytes> for Vec<u8> {
339 fn from(value: DynBytes) -> Self {
340 value.0
341 }
342}
343
344impl Deref for DynBytes {
345 type Target = [u8];
346
347 fn deref(&self) -> &Self::Target {
348 &self.0
349 }
350}
351
352impl Borrow<[u8]> for DynBytes {
353 fn borrow(&self) -> &[u8] {
354 &self.0
355 }
356}
357
358impl AsRef<[u8]> for DynBytes {
359 fn as_ref(&self) -> &[u8] {
360 &self.0
361 }
362}
363
364#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Encode)]
374#[cfg_attr(feature = "std", derive(TypeInfo))]
375#[repr(transparent)]
376pub struct ByteSlice<'a>(pub &'a [u8]);
377
378impl SolTypeEncode for ByteSlice<'_> {
380 type AlloyType = sol_data::Bytes;
381
382 const DEFAULT_VALUE: Self::DefaultType = DynSizeDefault;
383
384 fn tokenize(&self) -> Self::TokenType<'_> {
385 self.0
386 }
387}
388
389impl SolTopicEncode for ByteSlice<'_> {
390 fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
391 where
392 H: Fn(&[u8], &mut [u8; 32]),
393 {
394 let mut output = [0u8; 32];
395 hasher(self.0, &mut output);
396 output
397 }
398
399 fn topic_preimage(&self, buffer: &mut Vec<u8>) {
400 append_non_empty_member_topic_bytes(self.0, buffer);
401 }
402
403 fn default_topic_preimage(buffer: &mut Vec<u8>) {
404 buffer.extend([0u8; 32]);
405 }
406
407 fn topic_preimage_size(&self) -> usize {
408 non_zero_multiple_of_32(self.0.len())
409 }
410
411 fn default_topic_preimage_size() -> usize {
412 32
413 }
414}
415
416impl SolTokenType for ByteSlice<'_> {
417 type TokenType<'enc> = &'enc [u8];
418
419 type DefaultType = DynSizeDefault;
420}
421
422impl crate::sol::types::private::Sealed for ByteSlice<'_> {}
423
424impl<'a> SolEncode<'a> for ByteSlice<'_> {
426 type SolType = &'a ByteSlice<'a>;
427
428 fn to_sol_type(&'a self) -> Self::SolType {
429 self
430 }
431}
432
433impl<'a> From<&'a [u8]> for ByteSlice<'a> {
435 fn from(value: &'a [u8]) -> Self {
436 Self(value)
437 }
438}
439
440impl<'a> From<ByteSlice<'a>> for &'a [u8] {
441 fn from(value: ByteSlice<'a>) -> Self {
442 value.0
443 }
444}
445
446impl Deref for ByteSlice<'_> {
447 type Target = [u8];
448
449 fn deref(&self) -> &Self::Target {
450 self.0
451 }
452}
453
454impl Borrow<[u8]> for ByteSlice<'_> {
455 fn borrow(&self) -> &[u8] {
456 self.0
457 }
458}
459
460impl AsRef<[u8]> for ByteSlice<'_> {
461 fn as_ref(&self) -> &[u8] {
462 self.0
463 }
464}