alloy_provider/provider/multicall/
tuple.rs1use super::{
2 bindings::IMulticall3::Result as MulticallResult,
3 inner_types::{Dynamic, Failure, MulticallError, Result},
4};
5use alloy_primitives::Bytes;
6use alloy_sol_types::SolCall;
7
8mod private {
10 #[allow(unnameable_types)]
11 pub trait Sealed {}
12}
13use private::Sealed;
14
15#[doc(hidden)]
17#[allow(unnameable_types)]
18pub trait TuplePush<T> {
19 type Pushed;
21}
22
23#[doc(hidden)]
25pub trait CallTuple: Sealed {
26 type Returns;
73
74 type SuccessReturns;
76
77 fn decode_returns(data: &[Bytes]) -> Result<Self::SuccessReturns>;
81
82 fn decode_return_results(results: &[MulticallResult]) -> Result<Self::Returns>;
84
85 fn try_into_success(results: Self::Returns) -> Result<Self::SuccessReturns>;
87}
88
89#[derive(Debug, Clone)]
91pub struct Empty;
92
93impl Sealed for Empty {}
94
95impl<T: SolCall> TuplePush<T> for Empty {
96 type Pushed = (T,);
97}
98
99impl CallTuple for Empty {
100 type Returns = ();
101 type SuccessReturns = ();
102 fn decode_returns(_: &[Bytes]) -> Result<Self::SuccessReturns> {
103 Ok(())
104 }
105 fn decode_return_results(_results: &[MulticallResult]) -> Result<Self::Returns> {
106 Ok(())
107 }
108 fn try_into_success(_: Self::Returns) -> Result<Self::SuccessReturns> {
109 Ok(())
110 }
111}
112
113impl<D: SolCall> Sealed for Dynamic<D> {}
114
115macro_rules! impl_tuple {
117 ($($idx:tt => $ty:ident),+) => {
118 impl<$($ty: SolCall,)+> Sealed for ($($ty,)+) {}
119
120 impl<T: SolCall, $($ty: SolCall,)+> TuplePush<T> for ($($ty,)+) {
122 type Pushed = ($($ty,)+ T,);
123 }
124
125 impl<$($ty: SolCall,)+> CallTuple for ($($ty,)+) {
127 type Returns = ($(Result<$ty::Return, Failure>,)+);
129
130 type SuccessReturns = ($($ty::Return,)+);
131
132 fn decode_returns(data: &[Bytes]) -> Result<Self::SuccessReturns> {
133 if data.len() != count!($($ty),+) {
134 return Err(MulticallError::NoReturnData);
135 }
136
137 Ok(($($ty::abi_decode_returns(&data[$idx], false).map_err(MulticallError::DecodeError)?,)+))
139 }
140
141 fn decode_return_results(results: &[MulticallResult]) -> Result<Self::Returns> {
142 if results.len() != count!($($ty),+) {
143 return Err(MulticallError::NoReturnData);
144 }
145
146 Ok(($(
147 match &results[$idx].success {
148 true => Ok($ty::abi_decode_returns(&results[$idx].returnData, false).map_err(MulticallError::DecodeError)?),
149 false => Err(Failure { idx: $idx, return_data: results[$idx].returnData.clone() }),
150 },
151 )+))
152 }
153
154 fn try_into_success(results: Self::Returns) -> Result<Self::SuccessReturns> {
155 Ok(($(
156 match results.$idx {
157 Ok(value) => value,
158 Err(failure) => return Err(MulticallError::CallFailed(failure.return_data)),
159 },
160 )+))
161 }
162 }
163 };
164}
165
166macro_rules! count {
168 () => (0);
169 ($x:tt $(,$xs:tt)*) => (1 + count!($($xs),*));
170}
171
172impl_tuple!(0 => T1);
174impl_tuple!(0 => T1, 1 => T2);
175impl_tuple!(0 => T1, 1 => T2, 2 => T3);
176impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4);
177impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5);
178impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6);
179impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7);
180impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8);
181impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9);
182impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10);
183impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11);
184impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11, 11 => T12);
185impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11, 11 => T12, 12 => T13);
186impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11, 11 => T12, 12 => T13, 13 => T14);
187impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11, 11 => T12, 12 => T13, 13 => T14, 14 => T15);
188impl_tuple!(0 => T1, 1 => T2, 2 => T3, 3 => T4, 4 => T5, 5 => T6, 6 => T7, 7 => T8, 8 => T9, 9 => T10, 10 => T11, 11 => T12, 12 => T13, 13 => T14, 14 => T15, 15 => T16);