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 const MINIMUM_WORDS: usize;
60
61 fn decode_from(dec: &mut Decoder<'de, '_>) -> Result<Self>;
63
64 #[inline]
77 unsafe fn decode_many_from<'a>(
78 dec: &mut Decoder<'de, '_>,
79 out: &'a mut [MaybeUninit<Self>],
80 ) -> Result<&'a mut [Self]> {
81 try_init_each(out, || Self::decode_from(dec))
82 }
83
84 fn head_words(&self) -> usize;
86
87 fn tail_words(&self) -> usize;
89
90 #[inline]
92 fn total_words(&self) -> usize {
93 self.head_words() + self.tail_words()
94 }
95
96 fn head_append(&self, enc: &mut Encoder);
98
99 #[inline]
105 fn head_append_many(tokens: &[Self], enc: &mut Encoder) {
106 for token in tokens {
107 token.head_append(enc);
108 }
109 }
110
111 fn tail_append(&self, enc: &mut Encoder);
113}
114
115pub trait TokenSeq<'a>: Token<'a> {
121 const IS_TUPLE: bool = false;
123
124 fn encode_sequence(&self, enc: &mut Encoder);
126
127 fn decode_sequence(dec: &mut Decoder<'a, '_>) -> Result<Self>;
129}
130
131#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
133#[repr(transparent)]
134pub struct WordToken(pub Word);
135
136impl<T> From<&T> for WordToken
137where
138 T: Clone,
139 Self: From<T>,
140{
141 #[inline]
142 fn from(value: &T) -> Self {
143 Self::from(value.clone())
144 }
145}
146
147impl<T> From<&mut T> for WordToken
148where
149 T: Clone,
150 Self: From<T>,
151{
152 #[inline]
153 fn from(value: &mut T) -> Self {
154 Self::from(value.clone())
155 }
156}
157
158impl From<Word> for WordToken {
159 #[inline]
160 fn from(value: Word) -> Self {
161 Self(value)
162 }
163}
164
165impl From<WordToken> for Word {
166 #[inline]
167 fn from(value: WordToken) -> Self {
168 value.0
169 }
170}
171
172impl From<bool> for WordToken {
173 #[inline]
174 fn from(value: bool) -> Self {
175 U256::from(value as u64).into()
176 }
177}
178
179impl From<U256> for WordToken {
180 #[inline]
181 fn from(value: U256) -> Self {
182 Self(value.into())
183 }
184}
185
186impl From<I256> for WordToken {
187 #[inline]
188 fn from(value: I256) -> Self {
189 Self(value.into())
190 }
191}
192
193impl From<WordToken> for [u8; 32] {
194 #[inline]
195 fn from(value: WordToken) -> [u8; 32] {
196 value.0.into()
197 }
198}
199
200impl From<[u8; 32]> for WordToken {
201 #[inline]
202 fn from(value: [u8; 32]) -> Self {
203 Self(value.into())
204 }
205}
206
207impl AsRef<Word> for WordToken {
208 #[inline]
209 fn as_ref(&self) -> &Word {
210 &self.0
211 }
212}
213
214impl AsRef<[u8]> for WordToken {
215 #[inline]
216 fn as_ref(&self) -> &[u8] {
217 &self.0.0
218 }
219}
220
221impl<'a> Token<'a> for WordToken {
222 const DYNAMIC: bool = false;
223 const MINIMUM_WORDS: usize = 1;
224
225 #[inline]
226 fn decode_from(dec: &mut Decoder<'a, '_>) -> Result<Self> {
227 dec.take_word().copied().map(Self)
228 }
229
230 #[inline]
231 unsafe fn decode_many_from<'b>(
232 dec: &mut Decoder<'a, '_>,
233 out: &'b mut [MaybeUninit<Self>],
234 ) -> Result<&'b mut [Self]> {
235 let len = out.len();
236 let byte_len = len * Word::len_bytes();
237 let slice = dec.take_slice(byte_len)?;
238 unsafe {
242 core::ptr::copy_nonoverlapping(slice.as_ptr(), out.as_mut_ptr().cast::<u8>(), byte_len);
243 Ok(core::slice::from_raw_parts_mut(out.as_mut_ptr().cast::<Self>(), len))
244 }
245 }
246
247 #[inline]
248 fn head_words(&self) -> usize {
249 1
250 }
251
252 #[inline]
253 fn tail_words(&self) -> usize {
254 0
255 }
256
257 #[inline]
258 fn head_append(&self, enc: &mut Encoder) {
259 enc.append_word(self.0);
260 }
261
262 #[inline]
263 fn head_append_many(tokens: &[Self], enc: &mut Encoder) {
264 let words = unsafe { &*(tokens as *const [Self] as *const [Word]) };
266 enc.append_words(words);
267 }
268
269 #[inline]
270 fn tail_append(&self, _enc: &mut Encoder) {}
271}
272
273impl WordToken {
274 #[inline]
276 pub const fn new(array: [u8; 32]) -> Self {
277 Self(FixedBytes(array))
278 }
279
280 #[inline]
282 pub const fn as_slice(&self) -> &[u8] {
283 &self.0.0
284 }
285}
286
287#[derive(Clone, Debug, PartialEq, Eq)]
289pub struct FixedSeqToken<T, const N: usize>(pub [T; N]);
290
291impl<T, const N: usize> TryFrom<Vec<T>> for FixedSeqToken<T, N> {
292 type Error = <[T; N] as TryFrom<Vec<T>>>::Error;
293
294 #[inline]
295 fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
296 <[T; N]>::try_from(value).map(Self)
297 }
298}
299
300impl<T, const N: usize> From<[T; N]> for FixedSeqToken<T, N> {
301 #[inline]
302 fn from(value: [T; N]) -> Self {
303 Self(value)
304 }
305}
306
307impl<T, const N: usize> AsRef<[T; N]> for FixedSeqToken<T, N> {
308 #[inline]
309 fn as_ref(&self) -> &[T; N] {
310 &self.0
311 }
312}
313
314impl<'de, T: Token<'de>, const N: usize> Token<'de> for FixedSeqToken<T, N> {
315 const DYNAMIC: bool = T::DYNAMIC;
316 const MINIMUM_WORDS: usize = if Self::DYNAMIC { 1 } else { T::MINIMUM_WORDS.saturating_mul(N) };
317
318 #[inline]
319 fn decode_from(dec: &mut Decoder<'de, '_>) -> Result<Self> {
320 if Self::DYNAMIC {
321 dec.take_indirection().and_then(|mut child| Self::decode_sequence(&mut child))
322 } else {
323 Self::decode_sequence(dec)
324 }
325 }
326
327 #[inline]
328 fn head_words(&self) -> usize {
329 if Self::DYNAMIC {
330 1
332 } else {
333 self.0.iter().map(T::total_words).sum()
335 }
336 }
337
338 #[inline]
339 fn tail_words(&self) -> usize {
340 if Self::DYNAMIC {
341 self.0.iter().map(T::total_words).sum()
343 } else {
344 0
345 }
346 }
347
348 #[inline]
349 fn head_append(&self, enc: &mut Encoder) {
350 if Self::DYNAMIC {
351 enc.append_indirection();
352 } else {
353 T::head_append_many(&self.0, enc);
354 }
355 }
356
357 #[inline]
358 fn tail_append(&self, enc: &mut Encoder) {
359 if Self::DYNAMIC {
360 self.encode_sequence(enc);
361 }
362 }
363}
364
365impl<'de, T: Token<'de>, const N: usize> TokenSeq<'de> for FixedSeqToken<T, N> {
366 #[inline]
367 fn encode_sequence(&self, enc: &mut Encoder) {
368 encode_sequence_impl(&self.0, enc);
369 }
370
371 #[inline]
372 fn decode_sequence(dec: &mut Decoder<'de, '_>) -> Result<Self> {
373 dec.set_strict_head_words(T::MINIMUM_WORDS.checked_mul(N).ok_or(crate::Error::Overrun)?)?;
374 let mut arr = crate::impl_core::uninit_array::<T, N>();
375 unsafe {
378 T::decode_many_from(dec, &mut arr)?;
379 Ok(Self(crate::impl_core::array_assume_init(arr)))
380 }
381 }
382}
383
384impl<T, const N: usize> FixedSeqToken<T, N> {
385 #[allow(clippy::missing_const_for_fn)]
388 #[inline]
389 pub fn into_array(self) -> [T; N] {
390 self.0
391 }
392
393 #[inline]
395 pub const fn as_array(&self) -> &[T; N] {
396 &self.0
397 }
398
399 #[inline]
401 pub const fn as_slice(&self) -> &[T] {
402 &self.0
403 }
404}
405
406#[derive(Clone, Debug, PartialEq, Eq)]
408pub struct DynSeqToken<T>(pub Vec<T>);
409
410impl<T> From<Vec<T>> for DynSeqToken<T> {
411 #[inline]
412 fn from(value: Vec<T>) -> Self {
413 Self(value)
414 }
415}
416
417impl<T> AsRef<[T]> for DynSeqToken<T> {
418 #[inline]
419 fn as_ref(&self) -> &[T] {
420 self.0.as_ref()
421 }
422}
423
424impl<'de, T: Token<'de>> Token<'de> for DynSeqToken<T> {
425 const DYNAMIC: bool = true;
426 const MINIMUM_WORDS: usize = 1;
427
428 #[inline]
429 fn decode_from(dec: &mut Decoder<'de, '_>) -> Result<Self> {
430 let mut child = dec.take_indirection()?;
431 let len = child.take_offset()?;
432 if T::MINIMUM_WORDS == 0 {
433 debug_assert_eq!(core::mem::size_of::<T>(), 0);
434 if child.is_strict() && len != 0 {
435 return Err(crate::Error::ReserMismatch);
436 }
437 child.reserve(len)?;
439 #[allow(clippy::uninit_vec)]
440 let tokens = {
441 let mut tokens = Vec::new();
442 unsafe { tokens.set_len(len) };
447 tokens
448 };
449 return Ok(Self(tokens));
450 }
451 let required_words = T::MINIMUM_WORDS.checked_mul(len).ok_or(crate::Error::Overrun)?;
456 let mut child = child.raw_child()?;
457 child.set_strict_head_words(required_words)?;
458 if required_words > child.remaining_words() {
459 return Err(crate::Error::Overrun);
460 }
461 if child.is_strict() && T::DYNAMIC {
462 let mut tokens = Vec::new();
463 for _ in 0..len {
464 let token = T::decode_from(&mut child)?;
465 if tokens.len() == tokens.capacity() {
466 let additional = tokens.capacity().max(1).min(len - tokens.len());
467 child.reserve_elements::<T>(additional)?;
468 tokens.try_reserve_exact(additional)?;
469 }
470 tokens.push(token);
471 }
472 return Ok(Self(tokens));
473 }
474 child.reserve_elements::<T>(len)?;
475 let mut tokens = vec_try_with_capacity(len)?;
476 unsafe {
479 T::decode_many_from(&mut child, &mut tokens.spare_capacity_mut()[..len])?;
480 tokens.set_len(len);
481 }
482 Ok(Self(tokens))
483 }
484
485 #[inline]
486 fn head_words(&self) -> usize {
487 1
489 }
490
491 #[inline]
492 fn tail_words(&self) -> usize {
493 1 + self.0.iter().map(T::total_words).sum::<usize>()
495 }
496
497 #[inline]
498 fn head_append(&self, enc: &mut Encoder) {
499 enc.append_indirection();
500 }
501
502 #[inline]
503 fn tail_append(&self, enc: &mut Encoder) {
504 enc.append_seq_len(self.0.len());
505 self.encode_sequence(enc);
506 }
507}
508
509impl<'de, T: Token<'de>> TokenSeq<'de> for DynSeqToken<T> {
510 #[inline]
511 fn encode_sequence(&self, enc: &mut Encoder) {
512 encode_sequence_impl(&self.0, enc);
513 }
514
515 #[inline]
516 fn decode_sequence(dec: &mut Decoder<'de, '_>) -> Result<Self> {
517 dec.set_strict_head_words(Self::MINIMUM_WORDS)?;
518 Self::decode_from(dec)
519 }
520}
521
522impl<T> DynSeqToken<T> {
523 #[inline]
525 pub fn as_slice(&self) -> &[T] {
526 &self.0
527 }
528}
529
530#[derive(Clone, Copy, PartialEq, Eq)]
532pub struct PackedSeqToken<'a>(pub &'a [u8]);
533
534impl fmt::Debug for PackedSeqToken<'_> {
535 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
536 f.debug_tuple("PackedSeqToken").field(&hex::encode_prefixed(self.0)).finish()
537 }
538}
539
540impl<'a> From<&'a [u8]> for PackedSeqToken<'a> {
541 #[inline]
542 fn from(value: &'a [u8]) -> Self {
543 Self(value)
544 }
545}
546
547impl<'a> From<&'a Vec<u8>> for PackedSeqToken<'a> {
548 #[inline]
549 fn from(value: &'a Vec<u8>) -> Self {
550 Self(value.as_slice())
551 }
552}
553
554impl AsRef<[u8]> for PackedSeqToken<'_> {
555 #[inline]
556 fn as_ref(&self) -> &[u8] {
557 self.0
558 }
559}
560
561impl<'de: 'a, 'a> Token<'de> for PackedSeqToken<'a> {
562 const DYNAMIC: bool = true;
563 const MINIMUM_WORDS: usize = 1;
564
565 #[inline]
566 fn decode_from(dec: &mut Decoder<'de, '_>) -> Result<Self> {
567 let mut child = dec.take_indirection()?;
568 let len = child.take_offset()?;
569 let bytes = child.take_padded_slice(len)?;
570 child.reserve(len)?;
571 Ok(PackedSeqToken(bytes))
572 }
573
574 #[inline]
575 fn head_words(&self) -> usize {
576 1
578 }
579
580 #[inline]
581 fn tail_words(&self) -> usize {
582 1 + crate::utils::words_for(self.0)
584 }
585
586 #[inline]
587 fn head_append(&self, enc: &mut Encoder) {
588 enc.append_indirection();
589 }
590
591 #[inline]
592 fn tail_append(&self, enc: &mut Encoder) {
593 enc.append_packed_seq(self.0);
594 }
595}
596
597impl PackedSeqToken<'_> {
598 #[allow(clippy::missing_const_for_fn)]
601 #[inline]
602 pub fn into_vec(self) -> Vec<u8> {
603 self.0.to_vec()
604 }
605
606 pub fn into_bytes(self) -> Bytes {
608 Bytes::copy_from_slice(self.0)
609 }
610
611 #[inline]
613 pub const fn as_slice(&self) -> &[u8] {
614 self.0
615 }
616}
617
618macro_rules! tuple_impls {
619 ($count:literal $($ty:ident),+) => {
620 impl<'de, $($ty: Token<'de>,)+> Sealed for ($($ty,)+) {}
621
622 #[allow(non_snake_case)]
623 impl<'de, $($ty: Token<'de>,)+> Token<'de> for ($($ty,)+) {
624 const DYNAMIC: bool = $( <$ty as Token>::DYNAMIC )||+;
625 const MINIMUM_WORDS: usize = if Self::DYNAMIC {
626 1
627 } else {
628 0usize $( .saturating_add(<$ty as Token>::MINIMUM_WORDS) )+
629 };
630
631 #[inline]
632 fn decode_from(dec: &mut Decoder<'de, '_>) -> Result<Self> {
633 if Self::DYNAMIC {
636 dec.take_indirection().and_then(|mut child| Self::decode_sequence(&mut child))
637 } else {
638 Self::decode_sequence(dec)
639 }
640 }
641
642 #[inline]
643 fn head_words(&self) -> usize {
644 if Self::DYNAMIC {
645 1
647 } else {
648 let ($($ty,)+) = self;
650 0 $( + $ty.total_words() )+
651 }
652 }
653
654 #[inline]
655 fn tail_words(&self) -> usize {
656 if Self::DYNAMIC {
657 let ($($ty,)+) = self;
659 0 $( + $ty.total_words() )+
660 } else {
661 0
662 }
663 }
664
665 #[inline]
666 fn head_append(&self, enc: &mut Encoder) {
667 if Self::DYNAMIC {
668 enc.append_indirection();
669 } else {
670 let ($($ty,)+) = self;
671 $(
672 $ty.head_append(enc);
673 )+
674 }
675 }
676
677 #[inline]
678 fn tail_append(&self, enc: &mut Encoder) {
679 if Self::DYNAMIC {
680 self.encode_sequence(enc);
681 }
682 }
683 }
684
685 #[allow(non_snake_case)]
686 impl<'de, $($ty: Token<'de>,)+> TokenSeq<'de> for ($($ty,)+) {
687 const IS_TUPLE: bool = true;
688
689 fn encode_sequence(&self, enc: &mut Encoder) {
690 let ($($ty,)+) = self;
691 enc.push_offset(0 $( + $ty.head_words() )+);
692
693 $(
694 $ty.head_append(enc);
695 enc.bump_offset($ty.tail_words());
696 )+
697
698 $(
699 $ty.tail_append(enc);
700 )+
701
702 enc.pop_offset();
703 }
704
705 #[inline]
706 fn decode_sequence(dec: &mut Decoder<'de, '_>) -> Result<Self> {
707 let head_words = 0usize $(
708 .checked_add(<$ty as Token>::MINIMUM_WORDS)
709 .ok_or(crate::Error::Overrun)?
710 )+;
711 dec.set_strict_head_words(head_words)?;
712 Ok(($(
713 match <$ty as Token>::decode_from(dec) {
714 Ok(t) => t,
715 Err(e) => return Err(e),
716 },
717 )+))
718 }
719 }
720 };
721}
722
723impl<'de> Token<'de> for () {
724 const DYNAMIC: bool = false;
725 const MINIMUM_WORDS: usize = 0;
726
727 #[inline]
728 fn decode_from(_dec: &mut Decoder<'de, '_>) -> Result<Self> {
729 Ok(())
730 }
731
732 #[inline]
733 fn head_words(&self) -> usize {
734 0
735 }
736
737 #[inline]
738 fn tail_words(&self) -> usize {
739 0
740 }
741
742 #[inline]
743 fn head_append(&self, _enc: &mut Encoder) {}
744
745 #[inline]
746 fn tail_append(&self, _enc: &mut Encoder) {}
747}
748
749impl<'de> TokenSeq<'de> for () {
750 const IS_TUPLE: bool = true;
751
752 #[inline]
753 fn encode_sequence(&self, _enc: &mut Encoder) {}
754
755 #[inline]
756 fn decode_sequence(_dec: &mut Decoder<'de, '_>) -> Result<Self> {
757 Ok(())
758 }
759}
760
761all_the_tuples!(tuple_impls);
762
763fn encode_sequence_impl<'de, T: Token<'de>>(tokens: &[T], enc: &mut Encoder) {
766 if T::DYNAMIC {
767 enc.push_offset(tokens.iter().map(T::head_words).sum());
768
769 for inner in tokens {
770 inner.head_append(enc);
771 enc.bump_offset(inner.tail_words());
772 }
773 for inner in tokens {
774 inner.tail_append(enc);
775 }
776
777 enc.pop_offset();
778 } else {
779 T::head_append_many(tokens, enc);
780 }
781}
782
783#[inline]
788fn try_init_each<T, E, F>(out: &mut [MaybeUninit<T>], mut f: F) -> core::result::Result<&mut [T], E>
789where
790 F: FnMut() -> core::result::Result<T, E>,
791{
792 struct Guard<'a, T> {
793 buf: &'a mut [MaybeUninit<T>],
794 initialized: usize,
795 }
796 impl<T> Drop for Guard<'_, T> {
797 fn drop(&mut self) {
798 unsafe {
800 let ptr = self.buf.as_mut_ptr().cast::<T>();
801 ptr::drop_in_place(ptr::slice_from_raw_parts_mut(ptr, self.initialized));
802 }
803 }
804 }
805
806 let mut guard = Guard { buf: out, initialized: 0 };
807 for x in guard.buf.iter_mut() {
808 x.write(f()?);
809 guard.initialized += 1;
810 }
811 let buf = guard.buf as *mut [MaybeUninit<T>] as *mut [T];
812 mem::forget(guard);
813 Ok(unsafe { &mut *buf })
815}
816
817#[cfg(test)]
818mod tests {
819 use super::*;
820 use crate::{SolType, sol_data};
821 use alloy_primitives::B256;
822
823 macro_rules! assert_type_check {
824 ($sol:ty, $token:expr $(,)?) => {
825 assert!(<$sol>::type_check($token).is_ok())
826 };
827 }
828
829 macro_rules! assert_not_type_check {
830 ($sol:ty, $token:expr $(,)?) => {
831 assert!(<$sol>::type_check($token).is_err())
832 };
833 }
834
835 #[test]
836 fn test_type_check() {
837 assert_type_check!(
838 (sol_data::Uint<256>, sol_data::Bool),
839 &(WordToken(B256::default()), WordToken(B256::default())),
840 );
841
842 assert_not_type_check!(sol_data::Uint<8>, &Word::repeat_byte(0x11).into());
844 assert_not_type_check!(sol_data::Bool, &B256::repeat_byte(0x11).into());
845 assert_not_type_check!(sol_data::FixedBytes<31>, &B256::repeat_byte(0x11).into());
846
847 assert_type_check!(
848 (sol_data::Uint<32>, sol_data::Bool),
849 &(WordToken(B256::default()), WordToken(B256::default())),
850 );
851
852 assert_type_check!(
853 sol_data::Array<sol_data::Bool>,
854 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
855 );
856
857 assert_type_check!(
858 sol_data::Array<sol_data::Bool>,
859 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
860 );
861 assert_type_check!(
862 sol_data::Array<sol_data::Address>,
863 &DynSeqToken(vec![WordToken(B256::default()), WordToken(B256::default()),]),
864 );
865
866 assert_type_check!(
867 sol_data::FixedArray<sol_data::Bool, 2>,
868 &FixedSeqToken::<_, 2>([
869 WordToken(B256::default()),
870 WordToken(B256::default()),
871 ]),
872 );
873
874 assert_type_check!(
875 sol_data::FixedArray<sol_data::Address, 2>,
876 &FixedSeqToken::<_, 2>([
877 WordToken(B256::default()),
878 WordToken(B256::default()),
879 ]),
880 );
881 }
882}