use std::future::{Future, IntoFuture};
use std::marker::PhantomData;
use crate::network::Sandbox;
use crate::{Network, Worker};
use super::server::ValidatorKey;
pub(crate) type BoxFuture<'a, T> = std::pin::Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[async_trait::async_trait]
pub(crate) trait FromNetworkBuilder: Sized {
async fn from_builder<'a>(build: NetworkBuilder<'a, Self>) -> crate::result::Result<Self>;
}
pub struct NetworkBuilder<'a, T> {
pub(crate) name: &'a str,
pub(crate) rpc_addr: Option<String>,
pub(crate) validator_key: Option<ValidatorKey>,
pub(crate) api_key: Option<String>,
_network: PhantomData<T>,
}
impl<'a, T> IntoFuture for NetworkBuilder<'a, T>
where
T: FromNetworkBuilder + Network + Send + 'a,
{
type Output = crate::result::Result<Worker<T>>;
type IntoFuture = BoxFuture<'a, Self::Output>;
fn into_future(self) -> Self::IntoFuture {
let fut = async {
let network = FromNetworkBuilder::from_builder(self).await?;
Ok(Worker::new(network))
};
Box::pin(fut)
}
}
impl<'a, T> NetworkBuilder<'a, T> {
pub(crate) fn new(name: &'a str) -> Self {
Self {
name,
rpc_addr: None,
validator_key: None,
api_key: None,
_network: PhantomData,
}
}
pub fn rpc_addr(mut self, addr: &str) -> Self {
self.rpc_addr = Some(addr.into());
self
}
pub fn api_key(mut self, api_key: &str) -> Self {
self.api_key = Some(api_key.into());
self
}
}
impl NetworkBuilder<'_, Sandbox> {
pub fn validator_key(mut self, validator_key: ValidatorKey) -> Self {
self.validator_key = Some(validator_key);
self
}
}