1use crate::{
15 Result, Word,
16 abi::{Decoder, Encoder},
17};
18use alloc::vec::Vec;
19use alloy_primitives::{Bytes, FixedBytes, I256, U256, hex, utils::vec_try_with_capacity};
20use core::{fmt, mem, mem::MaybeUninit, ptr};
21
22#[allow(unknown_lints, unnameable_types)]
23mod sealed {
24 pub trait Sealed {}
25 impl Sealed for super::WordToken {}
26 impl Sealed for () {}
27 impl<T, const N: usize> Sealed for super::FixedSeqToken<T, N> {}
28 impl<T> Sealed for super::DynSeqToken<T> {}
29 impl Sealed for super::PackedSeqToken<'_> {}
30}
31use sealed::Sealed;
32
33pub trait Token<'de>: Sealed + Sized {
55 const DYNAMIC: bool;
57
58 fn decode_from(dec: &mut Decoder<'de>) -> Result<Self>;
60
61 #[inline]
74 unsafe fn decode_many_from<'a>(
75 dec: &mut Decoder<'de>,
76 out: &'a mut [MaybeUninit<Self>],
77 ) -> Result<&'a mut [Self]> {
78 try_init_each(out, || Self::decode_from(dec))
79 }
80
81 fn head_words(&self) -> usize;
83
84 fn tail_words(&self) -> usize;
86
87 #[inline]
89 fn total_words(&self) -> usize {
90 self.head_words() + self.tail_words()
91 }
92
93 fn head_append(&self, enc: &mut Encoder);
95
96 #[inline]
102 fn head_append_many(tokens: &[Self], enc: &mut Encoder) {
103 for token in tokens {
104 token.head_append(enc);
105 }
106 }
107
108 fn tail_append(&self, enc: &mut Encoder);
110}
111
112pub trait TokenSeq<'a>: Token<'a> {
118 const IS_TUPLE: bool = false;
120
121 fn encode_sequence(&self, enc: &mut Encoder);
123
124 fn decode_sequence(dec: &mut Decoder<'a>) -> Result<Self>;
126}
127
128#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
130#[repr(transparent)]
131pub struct WordToken(pub Word);
132
133impl<T> From<&T> for WordToken
134where
135 T: Clone,
136 Self: From<T>,
137{
138 #[inline]
139 fn from(value: &T) -> Self {
140 Self::from(value.clone())
141 }
142}
143
144impl<T> From<&mut T> for WordToken
145where
146 T: Clone,
147 Self: From<T>,
148{
149 #[inline]
150 fn from(value: &mut T) -> Self {
151 Self::from(value.clone())
152 }
153}
154
155impl From<Word> for WordToken {
156 #[inline]
157 fn from(value: Word) -> Self {
158 Self(value)
159 }
160}
161
162impl From<WordToken> for Word {
163 #[inline]
164 fn from(value: WordToken) -> Self {
165 value.0
166 }
167}
168
169impl From<bool> for WordToken {
170 #[inline]
171 fn from(value: bool) -> Self {
172 U256::from(value as u64).into()
173 }
174}
175
176impl From<U256> for WordToken {
177 #[inline]
178 fn from(value: U256) -> Self {
179 Self(value.into())
180 }
181}
182
183impl From<I256> for WordToken {
184 #[inline]
185 fn from(value: I256) -> Self {
186 Self(value.into())
187 }
188}
189
190impl From<WordToken> for [u8; 32] {
191 #[inline]
192 fn from(value: WordToken) -> [u8; 32] {
193 value.0.into()
194 }
195}
196
197impl From<[u8; 32]> for WordToken {
198 #[inline]
199 fn from(value: [u8; 32]) -> Self {
200 Self(value.into())
201 }
202}
203
204impl AsRef<Word> for WordToken {
205 #[inline]
206 fn as_ref(&self) -> &Word {
207 &self.0
208 }
209}
210
211impl AsRef<[u8]> for WordToken {
212 #[inline]
213 fn as_ref(&self) -> &[u8] {
214 &self.0.0
215 }
216}
217
218impl<'a> Token<'a> for WordToken {
219 const DYNAMIC: bool = false;
220
221 #[inline]
222 fn decode_from(dec: &mut Decoder<'a>) -> Result<Self> {
223 dec.take_word().copied().map(Self)
224 }
225
226 #[inline]
227 unsafe fn decode_many_from<'b>(
228 dec: &mut Decoder<'a>,
229 out: &'b mut [MaybeUninit<Self>],
230 ) -> Result<&'b mut [Self]> {
231 let len = out.len();
232 let byte_len = len * Word::len_bytes();
233 let slice = dec.take_slice(byte_len)?;
234 unsafe {
238 core::ptr::copy_nonoverlapping(slice.as_ptr(), out.as_mut_ptr().cast::<u8>(), byte_len);
239 Ok(core::slice::from_raw_parts_mut(out.as_mut_ptr().cast::<Self>(), len))
240 }
241 }
242
243 #[inline]
244 fn head_words(&self) -> usize {
245 1
246 }
247
248 #[inline]
249 fn tail_words(&self) -> usize {
250 0
251 }
252
253 #[inline]
254 fn head_append(&self, enc: &mut Encoder) {
255 enc.append_word(self.0);
256 }
257
258 #[inline]
259 fn head_append_many(tokens: &[Self], enc: &mut Encoder) {
260 let words = unsafe { &*(tokens as *const [Self] as *const [Word]) };
262 enc.append_words(words);
263 }
264
265 #[inline]
266 fn tail_append(&self, _enc: &mut Encoder) {}
267}
268
269impl WordToken {
270 #[inline]
272 pub const fn new(array: [u8; 32]) -> Self {
273 Self(FixedBytes(array))
274 }
275
276 #[inline]
278 pub const fn as_slice(&self) -> &[u8] {
279 &self.0.0
280 }
281}
282
283#[derive(Clone, Debug, PartialEq, Eq)]
285pub struct FixedSeqToken<T, const N: usize>(pub [T; N]);
286
287impl<T, const N: usize> TryFrom<Vec<T>> for FixedSeqToken<T, N> {
288 type Error = <[T; N] as TryFrom<Vec<T>>>::Error;
289
290 #[inline]
291 fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
292 <[T; N]>::try_from(value).map(Self)
293 }
294}
295
296impl<T, const N: usize> From<[T; N]> for FixedSeqToken<T, N> {
297 #[inline]
298 fn from(value: [T; N]) -> Self {
299 Self(value)
300 }
301}
302
303impl<T, const N: usize> AsRef<[T; N]> for FixedSeqToken<T, N> {
304 #[inline]
305 fn as_ref(&self) -> &[T; N] {
306 &self.0
307 }
308}
309
310impl<'de, T: Token<'de>, const N: usize> Token<'de> for FixedSeqToken<T, N> {
311 const DYNAMIC: bool = T::DYNAMIC;
312
313 #[inline]
314 fn decode_from(dec: &mut Decoder<'de>) -> Result<Self> {
315 if Self::DYNAMIC {
316 dec.take_indirection().and_then(|mut child| Self::decode_sequence(&mut child))
317 } else {
318 Self::decode_sequence(dec)
319 }
320 }
321
322 #[inline]
323 fn head_words(&self) -> usize {
324 if Self::DYNAMIC {
325 1
327 } else {
328 self.0.iter().map(T::total_words).sum()
330 }
331 }
332
333 #[inline]
334 fn tail_words(&self) -> usize {
335 if Self::DYNAMIC {
336 self.0.iter().map(T::total_words).sum()
338 } else {
339 0
340 }
341 }
342
343 #[inline]
344 fn head_append(&self, enc: &mut Encoder) {
345 if Self::DYNAMIC {
346 enc.append_indirection();
347 } else {
348 T::head_append_many(&self.0, enc);
349 }
350 }
351
352 #[inline]
353 fn tail_append(&self, enc: &mut Encoder) {
354 if Self::DYNAMIC {
355 self.encode_sequence(enc);
356 }
357 }
358}
359
360impl<'de, T: Token<'de>, const N: usize> TokenSeq<'de> for FixedSeqToken<T, N> {
361 #[inline]
362 fn encode_sequence(&self, enc: &mut Encoder) {
363 encode_sequence_impl(&self.0, enc);
364 }
365
366 #[inline]
367 fn decode_sequence(dec: &mut Decoder<'de>) -> Result<Self> {
368 let mut arr = crate::impl_core::uninit_array::<T, N>();
369 unsafe {
372 T::decode_many_from(dec, &mut arr)?;
373 Ok(Self(crate::impl_core::array_assume_init(arr)))
374 }
375 }
376}
377
378impl<T, const N: usize> FixedSeqToken<T, N> {
379 #[allow(clippy::missing_const_for_fn)]
382 #[inline]
383 pub fn into_array(self) -> [T; N] {
384 self.0
385 }
386
387 #[inline]
389 pub const fn as_array(&self) -> &[T; N] {
390 &self.0
391 }
392
393 #[inline]
395 pub const fn as_slice(&self) -> &[T] {
396 &self.0
397 }
398}
399
400#[derive(Clone, Debug, PartialEq, Eq)]
402pub struct DynSeqToken<T>(pub Vec<T>);
403
404impl<T> From<Vec<T>> for DynSeqToken<T> {
405 #[inline]
406 fn from(value: Vec<T>) -> Self {
407 Self(value)
408 }
409}
410
411impl<T> AsRef<[T]> for DynSeqToken<T> {
412 #[inline]
413 fn as_ref(&self) -> &[T] {
414 self.0.as_ref()
415 }
416}
417
418impl<'de, T: Token<'de>> Token<'de> for DynSeqToken<T> {
419 const DYNAMIC: bool = true;
420
421 #[inline]
422 fn decode_from(dec: &mut Decoder<'de>) -> Result<Self> {
423 let mut child = dec.take_indirection()?;
424 let len = child.take_offset()?;
425 let mut child = child.raw_child()?;
430 let mut tokens = vec_try_with_capacity(len)?;
431 unsafe {
434 T::decode_many_from(&mut child, &mut tokens.spare_capacity_mut()[..len])?;
435 tokens.set_len(len);
436 }
437 Ok(Self(tokens))
438 }
439
440 #[inline]
441 fn head_words(&self) -> usize {
442 1
444 }
445
446 #[inline]
447 fn tail_words(&self) -> usize {
448 1 + self.0.iter().map(T::total_words).sum::<usize>()
450 }
451
452 #[inline]
453 fn head_append(&self, enc: &mut Encoder) {
454 enc.append_indirection();
455 }
456
457 #[inline]
458 fn tail_append(&self, enc: &mut Encoder) {
459 enc.append_seq_len(self.0.len());
460 self.encode_sequence(enc);
461 }
462}
463
464impl<'de, T: Token<'de>> TokenSeq<'de> for DynSeqToken<T> {
465 #[inline]
466 fn encode_sequence(&self, enc: &mut Encoder) {
467 encode_sequence_impl(&self.0, enc);
468 }
469
470 #[inline]
471 fn decode_sequence(dec: &mut Decoder<'de>) -> Result<Self> {
472 Self::decode_from(dec)
473 }
474}
475
476impl<T> DynSeqToken<T> {
477 #[inline]
479 pub fn as_slice(&self) -> &[T] {
480 &self.0
481 }
482}
483
484#[derive(Clone, Copy, PartialEq, Eq)]
486pub struct PackedSeqToken<'a>(pub &'a [u8]);
487
488impl fmt::Debug for PackedSeqToken<'_> {
489 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
490 f.debug_tuple("PackedSeqToken").field(&hex::encode_prefixed(self.0)).finish()
491 }
492}
493
494impl<'a> From<&'a [u8]> for PackedSeqToken<'a> {
495 #[inline]
496 fn from(value: &'a [u8]) -> Self {
497 Self(value)
498 }
499}
500
501impl<'a> From<&'a Vec<u8>> for PackedSeqToken<'a> {
502 #[inline]
503 fn from(value: &'a Vec<u8>) -> Self {
504 Self(value.as_slice())
505 }
506}
507
508impl AsRef<[u8]> for PackedSeqToken<'_> {
509 #[inline]
510 fn as_ref(&self) -> &[u8] {
511 self.0
512 }
513}
514
515impl<'de: 'a, 'a> Token<'de> for PackedSeqToken<'a> {
516 const DYNAMIC: bool = true;
517
518 #[inline]
519 fn decode_from(dec: &mut Decoder<'de>) -> Result<Self> {
520 let mut child = dec.take_indirection()?;
521 let len = child.take_offset()?;
522 let bytes = child.peek_len(len)?;
523 Ok(PackedSeqToken(bytes))
524 }
525
526 #[inline]
527 fn head_words(&self) -> usize {
528 1
530 }
531
532 #[inline]
533 fn tail_words(&self) -> usize {
534 1 + crate::utils::words_for(self.0)
536 }
537
538 #[inline]
539 fn head_append(&self, enc: &mut Encoder) {
540 enc.append_indirection();
541 }
542
543 #[inline]
544 fn tail_append(&self, enc: &mut Encoder) {
545 enc.append_packed_seq(self.0);
546 }
547}
548
549impl PackedSeqToken<'_> {
550 #[allow(clippy::missing_const_for_fn)]
553 #[inline]
554 pub fn into_vec(self) -> Vec<u8> {
555 self.0.to_vec()
556 }
557
558 pub fn into_bytes(self) -> Bytes {
560 Bytes::copy_from_slice(self.0)
561 }
562
563 #[inline]
565 pub const fn as_slice(&self) -> &[u8] {
566 self.0
567 }
568}
569
570macro_rules! tuple_impls {
571 ($count:literal $($ty:ident),+) => {
572 impl<'de, $($ty: Token<'de>,)+> Sealed for ($($ty,)+) {}
573
574 #[allow(non_snake_case)]
575 impl<'de, $($ty: Token<'de>,)+> Token<'de> for ($($ty,)+) {
576 const DYNAMIC: bool = $( <$ty as Token>::DYNAMIC )||+;
577
578 #[inline]
579 fn decode_from(dec: &mut Decoder<'de>) -> Result<Self> {
580 if Self::DYNAMIC {
583 dec.take_indirection().and_then(|mut child| Self::decode_sequence(&mut child))
584 } else {
585 Self::decode_sequence(dec)
586 }
587 }
588
589 #[inline]
590 fn head_words(&self) -> usize {
591 if Self::DYNAMIC {
592 1
594 } else {
595 let ($($ty,)+) = self;
597 0 $( + $ty.total_words() )+
598 }
599 }
600
601 #[inline]
602 fn tail_words(&self) -> usize {
603 if Self::DYNAMIC {
604 let ($($ty,)+) = self;
606 0 $( + $ty.total_words() )+
607 } else {
608 0
609 }
610 }
611
612 #[inline]
613 fn head_append(&self, enc: &mut Encoder) {
614 if Self::DYNAMIC {
615 enc.append_indirection();
616 } else {
617 let ($($ty,)+) = self;
618 $(
619 $ty.head_append(enc);
620 )+
621 }
622 }
623
624 #[inline]
625 fn tail_append(&self, enc: &mut Encoder) {
626 if Self::DYNAMIC {
627 self.encode_sequence(enc);
628 }
629 }
630 }
631
632 #[allow(non_snake_case)]
633 impl<'de, $($ty: Token<'de>,)+> TokenSeq<'de> for ($($ty,)+) {
634 const IS_TUPLE: bool = true;
635
636 fn encode_sequence(&self, enc: &mut Encoder) {
637 let ($($ty,)+) = self;
638 enc.push_offset(0 $( + $ty.head_words() )+);
639
640 $(
641 $ty.head_append(enc);
642 enc.bump_offset($ty.tail_words());
643 )+
644
645 $(
646 $ty.tail_append(enc);
647 )+
648
649 enc.pop_offset();
650 }
651
652 #[inline]
653 fn decode_sequence(dec: &mut Decoder<'de>) -> Result<Self> {
654 Ok(($(
655 match <$ty as Token>::decode_from(dec) {
656 Ok(t) => t,
657 Err(e) => return Err(e),
658 },
659 )+))
660 }
661 }
662 };
663}
664
665impl<'de> Token<'de> for () {
666 const DYNAMIC: bool = false;
667
668 #[inline]
669 fn decode_from(_dec: &mut Decoder<'de>) -> Result<Self> {
670 Ok(())
671 }
672
673 #[inline]
674 fn head_words(&self) -> usize {
675 0
676 }
677
678 #[inline]
679 fn tail_words(&self) -> usize {
680 0
681 }
682
683 #[inline]
684 fn head_append(&self, _enc: &mut Encoder) {}
685
686 #[inline]
687 fn tail_append(&self, _enc: &mut Encoder) {}
688}
689
690impl<'de> TokenSeq<'de> for () {
691 const IS_TUPLE: bool = true;
692
693 #[inline]
694 fn encode_sequence(&self, _enc: &mut Encoder) {}
695
696 #[inline]
697 fn decode_sequence(_dec: &mut Decoder<'de>) -> Result<Self> {
698 Ok(())
699 }
700}
701
702all_the_tuples!(tuple_impls);
703
704fn encode_sequence_impl<'de, T: Token<'de>>(tokens: &[T], enc: &mut Encoder) {
707 if T::DYNAMIC {
708 enc.push_offset(tokens.iter().map(T::head_words).sum());
709
710 for inner in tokens {
711 inner.head_append(enc);
712 enc.bump_offset(inner.tail_words());
713 }
714 for inner in tokens {
715 inner.tail_append(enc);
716 }
717
718 enc.pop_offset();
719 } else {
720 T::head_append_many(tokens, enc);
721 }
722}
723
724#[inline]
729fn try_init_each<T, E, F>(out: &mut [MaybeUninit<T>], mut f: F) -> core::result::Result<&mut [T], E>
730where
731 F: FnMut() -> core::result::Result<T, E>,
732{
733 struct Guard<'a, T> {
734 buf: &'a mut [MaybeUninit<T>],
735 initialized: usize,
736 }
737 impl<T> Drop for Guard<'_, T> {
738 fn drop(&mut self) {
739 unsafe {
741 let ptr = self.buf.as_mut_ptr().cast::<T>();
742 ptr::drop_in_place(ptr::slice_from_raw_parts_mut(ptr, self.initialized));
743 }
744 }
745 }
746
747 let mut guard = Guard { buf: out, initialized: 0 };
748 for x in guard.buf.iter_mut() {
749 x.write(f()?);
750 guard.initialized += 1;
751 }
752 let buf = guard.buf as *mut [MaybeUninit<T>] as *mut [T];
753 mem::forget(guard);
754 Ok(unsafe { &mut *buf })
756}
757
758#[cfg(test)]
759mod tests {
760 use super::*;
761 use crate::{SolType, sol_data};
762 use alloy_primitives::B256;
763
764 macro_rules! assert_type_check {
765 ($sol:ty, $token:expr $(,)?) => {
766 assert!(<$sol>::type_check($token).is_ok())
767 };
768 }
769
770 macro_rules! assert_not_type_check {
771 ($sol:ty, $token:expr $(,)?) => {
772 assert!(<$sol>::type_check($token).is_err())
773 };
774 }
775
776 #[test]
777 fn test_type_check() {
778 assert_type_check!(
779 (sol_data::Uint<256>, sol_data::Bool),
780 &(WordToken(B256::default()), WordToken(B256::default())),
781 );
782
783 assert_not_type_check!(sol_data::Uint<8>, &Word::repeat_byte(0x11).into());
785 assert_not_type_check!(sol_data::Bool, &B256::repeat_byte(0x11).into());
786 assert_not_type_check!(sol_data::FixedBytes<31>, &B256::repeat_byte(0x11).into());
787
788 assert_type_check!(
789 (sol_data::Uint<32>, sol_data::Bool),
790 &(WordToken(B256::default()), WordToken(B256::default())),
791 );
792
793 assert_type_check!(
794 sol_data::Array<sol_data::Bool>,
795 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
796 );
797
798 assert_type_check!(
799 sol_data::Array<sol_data::Bool>,
800 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
801 );
802 assert_type_check!(
803 sol_data::Array<sol_data::Address>,
804 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
805 );
806
807 assert_type_check!(
808 sol_data::FixedArray<sol_data::Bool, 2>,
809 &FixedSeqToken::<_, 2>([
810 WordToken(B256::default()),
811 WordToken(B256::default()),
812 ]),
813 );
814
815 assert_type_check!(
816 sol_data::FixedArray<sol_data::Address, 2>,
817 &FixedSeqToken::<_, 2>([
818 WordToken(B256::default()),
819 WordToken(B256::default()),
820 ]),
821 );
822 }
823}