alloy_provider/fillers/
join_fill.rs1use crate::{
2 fillers::{FillProvider, FillerControlFlow, TxFiller},
3 provider::SendableTx,
4 Provider, ProviderLayer,
5};
6use alloy_network::Network;
7use alloy_transport::TransportResult;
8use futures::try_join;
9
10#[derive(Clone, Copy, Debug, Default)]
19pub struct JoinFill<L, R> {
20 left: L,
21 right: R,
22}
23
24impl<L, R> JoinFill<L, R> {
25 pub const fn new(left: L, right: R) -> Self {
27 Self { left, right }
28 }
29
30 pub const fn left(&self) -> &L {
32 &self.left
33 }
34
35 pub const fn right(&self) -> &R {
37 &self.right
38 }
39
40 pub const fn left_mut(&mut self) -> &mut L {
42 &mut self.left
43 }
44
45 pub const fn right_mut(&mut self) -> &mut R {
47 &mut self.right
48 }
49
50 pub fn map_left<F, T>(self, f: F) -> JoinFill<T, R>
52 where
53 F: FnOnce(L) -> T,
54 {
55 JoinFill::new(f(self.left), self.right)
56 }
57
58 pub fn map_right<F, T>(self, f: F) -> JoinFill<L, T>
60 where
61 F: FnOnce(R) -> T,
62 {
63 JoinFill::new(self.left, f(self.right))
64 }
65}
66
67impl<L, R> JoinFill<L, R> {
68 async fn prepare_left<P, N>(
70 &self,
71 provider: &P,
72 tx: &N::TransactionRequest,
73 ) -> TransportResult<Option<L::Fillable>>
74 where
75 P: Provider<N>,
76 L: TxFiller<N>,
77 N: Network,
78 {
79 if self.left.ready(tx) {
80 self.left.prepare(provider, tx).await.map(Some)
81 } else {
82 Ok(None)
83 }
84 }
85
86 async fn prepare_right<P, N>(
88 &self,
89 provider: &P,
90 tx: &N::TransactionRequest,
91 ) -> TransportResult<Option<R::Fillable>>
92 where
93 P: Provider<N>,
94 R: TxFiller<N>,
95 N: Network,
96 {
97 if self.right.ready(tx) {
98 self.right.prepare(provider, tx).await.map(Some)
99 } else {
100 Ok(None)
101 }
102 }
103}
104
105impl<L, R, N> TxFiller<N> for JoinFill<L, R>
106where
107 L: TxFiller<N>,
108 R: TxFiller<N>,
109 N: Network,
110{
111 type Fillable = (Option<L::Fillable>, Option<R::Fillable>);
112
113 fn status(&self, tx: &N::TransactionRequest) -> FillerControlFlow {
114 self.left.status(tx).absorb(self.right.status(tx))
115 }
116
117 fn fill_sync(&self, tx: &mut SendableTx<N>) {
118 self.left.fill_sync(tx);
119 self.right.fill_sync(tx);
120 }
121
122 async fn prepare<P>(
123 &self,
124 provider: &P,
125 tx: &N::TransactionRequest,
126 ) -> TransportResult<Self::Fillable>
127 where
128 P: Provider<N>,
129 {
130 try_join!(self.prepare_left(provider, tx), self.prepare_right(provider, tx))
131 }
132
133 async fn fill(
134 &self,
135 to_fill: Self::Fillable,
136 mut tx: SendableTx<N>,
137 ) -> TransportResult<SendableTx<N>> {
138 if let Some(to_fill) = to_fill.0 {
139 tx = self.left.fill(to_fill, tx).await?;
140 };
141 if let Some(to_fill) = to_fill.1 {
142 tx = self.right.fill(to_fill, tx).await?;
143 };
144 Ok(tx)
145 }
146
147 async fn prepare_call(
148 &self,
149 tx: &mut <N as Network>::TransactionRequest,
150 ) -> TransportResult<()> {
151 self.left.prepare_call(tx).await?;
152 self.right.prepare_call(tx).await?;
153 Ok(())
154 }
155
156 fn prepare_call_sync(
157 &self,
158 tx: &mut <N as Network>::TransactionRequest,
159 ) -> TransportResult<()> {
160 self.left.prepare_call_sync(tx)?;
161 self.right.prepare_call_sync(tx)?;
162 Ok(())
163 }
164}
165
166impl<L, R, P, N> ProviderLayer<P, N> for JoinFill<L, R>
167where
168 L: TxFiller<N>,
169 R: TxFiller<N>,
170 P: Provider<N>,
171 N: Network,
172{
173 type Provider = FillProvider<Self, P, N>;
174
175 fn layer(&self, inner: P) -> Self::Provider {
176 FillProvider::new(inner, self.clone())
177 }
178}