Skip to content

Commit 2afe550

Browse files
authored
feat(provider): add ProviderBuilder apply helpers (#3901)
1 parent 177c173 commit 2afe550

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

crates/provider/src/builder.rs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,28 @@ impl<L, N: Network> ProviderBuilder<L, Identity, N> {
184184
}
185185

186186
impl<L, F, N> ProviderBuilder<L, F, N> {
187+
/// Apply a function to this builder.
188+
///
189+
/// This is useful for extracting reusable builder-style helper functions without manually
190+
/// reconstructing the [`ProviderBuilder`].
191+
pub fn apply<T>(self, f: impl FnOnce(Self) -> T) -> T {
192+
f(self)
193+
}
194+
195+
/// Map the layer stack to a new type.
196+
///
197+
/// This is useful for customizing or replacing the accumulated layers in a reusable helper.
198+
pub fn map_layer<L2>(self, f: impl FnOnce(L) -> L2) -> ProviderBuilder<L2, F, N> {
199+
ProviderBuilder { layer: f(self.layer), filler: self.filler, network: PhantomData }
200+
}
201+
202+
/// Map the filler stack to a new type.
203+
///
204+
/// This is useful for customizing or replacing the accumulated fillers in a reusable helper.
205+
pub fn map_filler<F2>(self, f: impl FnOnce(F) -> F2) -> ProviderBuilder<L, F2, N> {
206+
ProviderBuilder { layer: self.layer, filler: f(self.filler), network: PhantomData }
207+
}
208+
187209
/// Add a layer to the stack being built. This is similar to
188210
/// [`tower::ServiceBuilder::layer`].
189211
///
@@ -196,22 +218,14 @@ impl<L, F, N> ProviderBuilder<L, F, N> {
196218
/// [`tower::ServiceBuilder::layer`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html#method.layer
197219
/// [`tower::ServiceBuilder`]: https://docs.rs/tower/latest/tower/struct.ServiceBuilder.html
198220
pub fn layer<Inner>(self, layer: Inner) -> ProviderBuilder<Stack<Inner, L>, F, N> {
199-
ProviderBuilder {
200-
layer: Stack::new(layer, self.layer),
201-
filler: self.filler,
202-
network: PhantomData,
203-
}
221+
self.map_layer(|current| Stack::new(layer, current))
204222
}
205223

206224
/// Add a transaction filler to the stack being built. Transaction fillers
207225
/// are used to fill in missing fields on transactions before they are sent,
208226
/// and are all joined to form the outermost layer of the stack.
209227
pub fn filler<F2>(self, filler: F2) -> ProviderBuilder<L, JoinFill<F, F2>, N> {
210-
ProviderBuilder {
211-
layer: self.layer,
212-
filler: JoinFill::new(self.filler, filler),
213-
network: PhantomData,
214-
}
228+
self.map_filler(|current| JoinFill::new(current, filler))
215229
}
216230

217231
/// Change the network.
@@ -832,6 +846,29 @@ mod tests {
832846
> = builder;
833847
}
834848

849+
#[test]
850+
fn apply_transforms_builder() {
851+
let builder = ProviderBuilder::new()
852+
.apply(|builder| builder.disable_recommended_fillers().with_gas_estimation());
853+
854+
let _: ProviderBuilder<Identity, JoinFill<Identity, GasFiller>, Ethereum> = builder;
855+
}
856+
857+
#[test]
858+
fn map_filler_replaces_fillers() {
859+
let builder = ProviderBuilder::new().map_filler(|_| GasFiller::default());
860+
861+
let _: ProviderBuilder<Identity, GasFiller, Ethereum> = builder;
862+
}
863+
864+
#[test]
865+
fn map_layer_replaces_layers() {
866+
let builder = ProviderBuilder::<Identity, Identity>::default()
867+
.map_layer(|_| ChainLayer::new(NamedChain::Mainnet));
868+
869+
let _: ProviderBuilder<ChainLayer, Identity, Ethereum> = builder;
870+
}
871+
835872
#[tokio::test]
836873
async fn network_swap_works_at_runtime() {
837874
// Verify that `ProviderBuilder::new().network::<AnyNetwork>()` produces a working provider.

0 commit comments

Comments
 (0)