use std::iter::repeat_with;
use multiaddr::Multiaddr;
use rand::rngs::OsRng;
use super::{net_address::NetAddressesFactory, TestFactory, TestFactoryError};
use crate::{
net_address::{MultiaddressesWithStats, PeerAddressSource},
peer_manager::{NodeId, Peer, PeerFeatures, PeerFlags},
types::CommsPublicKey,
};
pub fn create_many(n: usize) -> PeersFactory {
PeersFactory::default().with_count(n)
}
pub fn create() -> PeerFactory {
PeerFactory::default()
}
#[derive(Default, Clone)]
pub struct PeerFactory {
node_id: Option<NodeId>,
flags: Option<PeerFlags>,
public_key: Option<CommsPublicKey>,
net_addresses_factory: NetAddressesFactory,
net_addresses: Option<Vec<Multiaddr>>,
peer_features: PeerFeatures,
}
impl PeerFactory {
factory_setter!(with_node_id, node_id, Option<NodeId>);
factory_setter!(with_flags, flags, Option<PeerFlags>);
factory_setter!(with_public_key, public_key, Option<CommsPublicKey>);
factory_setter!(with_peer_features, peer_features, PeerFeatures);
factory_setter!(with_net_addresses_factory, net_addresses_factory, NetAddressesFactory);
factory_setter!(with_net_addresses, net_addresses, Option<Vec<Multiaddr>>);
}
impl TestFactory for PeerFactory {
type Object = Peer;
fn build(self) -> Result<Self::Object, TestFactoryError> {
let flags = self.flags.or_else(|| Some(PeerFlags::empty())).unwrap();
let public_key = self
.public_key
.clone()
.or_else(|| {
let (_, pk) = CommsPublicKey::random_keypair(&mut OsRng);
Some(pk)
})
.unwrap();
let node_id = self
.node_id
.clone()
.or_else(|| Some(NodeId::from_key(&public_key)))
.unwrap();
let default = self.net_addresses_factory.build().ok();
let addresses = self
.net_addresses
.or(default)
.ok_or_else(|| TestFactoryError::BuildFailed("Failed to build net addresses for peer".to_string()))?;
Ok(Peer::new(
public_key,
node_id,
MultiaddressesWithStats::from_addresses_with_source(addresses, &PeerAddressSource::Config),
flags,
self.peer_features,
Default::default(),
Default::default(),
))
}
}
#[derive(Default)]
pub struct PeersFactory {
count: Option<usize>,
peer_factory: PeerFactory,
}
impl PeersFactory {
factory_setter!(with_count, count, Option<usize>);
factory_setter!(with_factory, peer_factory, PeerFactory);
fn create_peer(&self) -> Peer {
self.peer_factory.clone().build().unwrap()
}
}
impl TestFactory for PeersFactory {
type Object = Vec<Peer>;
fn build(self) -> Result<Self::Object, TestFactoryError> {
Ok(repeat_with(|| self.create_peer())
.take(self.count.unwrap_or(1))
.collect::<Vec<Peer>>())
}
}