pub mod estimate_fee;
pub mod surround;
use std::{future::Future, ops::Deref};
use solana_sdk::signer::Signer;
use crate::{
bundle_builder::{BundleBuilder, BundleOptions},
transaction_builder::TransactionBuilder,
};
pub use self::{
estimate_fee::{EstimateFee, SetExecutionFee},
surround::Surround,
};
pub trait MakeBundleBuilder<'a, C> {
fn build_with_options(
&mut self,
options: BundleOptions,
) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>>;
fn build(&mut self) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
self.build_with_options(Default::default())
}
}
impl<'a, C, T> MakeBundleBuilder<'a, C> for &mut T
where
T: MakeBundleBuilder<'a, C>,
{
fn build(&mut self) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
(**self).build()
}
fn build_with_options(
&mut self,
options: BundleOptions,
) -> impl Future<Output = crate::Result<BundleBuilder<'a, C>>> {
(**self).build_with_options(options)
}
}
pub trait MakeBundleBuilderExt<'a, C>: MakeBundleBuilder<'a, C> {
fn surround(self) -> Surround<'a, C, Self>
where
Self: Sized,
{
self.into()
}
}
impl<'a, C, T: MakeBundleBuilder<'a, C> + ?Sized> MakeBundleBuilderExt<'a, C> for T {}
impl<'a, C: Deref<Target = impl Signer> + Clone> MakeBundleBuilder<'a, C>
for TransactionBuilder<'a, C>
{
async fn build_with_options(
&mut self,
options: BundleOptions,
) -> crate::Result<BundleBuilder<'a, C>> {
self.clone().into_bundle_with_options(options)
}
}
pub struct OnceMakeBundleBuilder<'a, C>(Option<BundleBuilder<'a, C>>);
impl<'a, C> From<BundleBuilder<'a, C>> for OnceMakeBundleBuilder<'a, C> {
fn from(value: BundleBuilder<'a, C>) -> Self {
Self(Some(value))
}
}
pub fn once_make_bundle<C>(bundle: BundleBuilder<C>) -> OnceMakeBundleBuilder<'_, C> {
bundle.into()
}
impl<'a, C> MakeBundleBuilder<'a, C> for OnceMakeBundleBuilder<'a, C> {
async fn build_with_options(
&mut self,
options: BundleOptions,
) -> crate::Result<BundleBuilder<'a, C>> {
let mut bundle = self
.0
.take()
.ok_or_else(|| crate::Error::custom("`OnceMakeBundleBuilder` can only be used once"))?;
bundle.set_options(options);
Ok(bundle)
}
}