|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
use alloc::boxed::Box; |
|
|
|
|
use alloc::string::String; |
|
|
|
|
use alloc::vec::Vec; |
|
|
|
|
use alloc::vec; |
|
|
|
|
use crate::interface::{Interface, TargetingData}; |
|
|
|
|
use crate::message::MessageBytes; |
|
|
|
|
use crate::res::IFResult; |
|
|
|
@ -10,7 +11,7 @@ use rayon::prelude::*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// An identification of a peer - something that we can use to send a message to id
|
|
|
|
|
#[derive(Clone, Debug)] |
|
|
|
|
#[derive(Clone, Debug, PartialEq)] |
|
|
|
|
pub struct PeerInfo { |
|
|
|
|
/// Something to locally identify this peer
|
|
|
|
|
pub peer_id: u64, |
|
|
|
@ -38,6 +39,11 @@ pub struct Transport {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Transport { |
|
|
|
|
/// Create new transport with given interfaces
|
|
|
|
|
pub fn new(interfaces: Vec<Box<dyn Interface>>) -> Self { |
|
|
|
|
Self { interfaces, peers: vec![] } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Find a peer in `self.peers` by its id
|
|
|
|
|
fn get_peer_by_id(&self, peer_id: u64) -> Option<PeerInfo> { |
|
|
|
|
self.peers.iter().find(|peer| peer.peer_id == peer_id).cloned() |
|
|
|
@ -73,16 +79,16 @@ impl Transport {
|
|
|
|
|
// Broadcast
|
|
|
|
|
None => { |
|
|
|
|
#[cfg(not(std))] |
|
|
|
|
{ |
|
|
|
|
for interface in &mut self.interfaces { |
|
|
|
|
interface.send(&message, None)?; |
|
|
|
|
{ |
|
|
|
|
for interface in &mut self.interfaces { |
|
|
|
|
interface.send(&message, None)?; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// If we have concurrency, we will do it concurrently
|
|
|
|
|
#[cfg(std)] |
|
|
|
|
{ |
|
|
|
|
self.interfaces.par_iter_mut().map(|interface| interface.send(&message, None)).for_each(drop); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
self.interfaces.par_iter_mut().map(|interface| interface.send(&message, None)).for_each(drop); |
|
|
|
|
} |
|
|
|
|
Ok(()) |
|
|
|
|
} |
|
|
|
|
// Singlecast
|
|
|
|
@ -93,3 +99,35 @@ impl Transport {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
|
use crate::interface::test_interface::TestInterface; |
|
|
|
|
#[cfg(test)] |
|
|
|
|
use alloc::string::ToString; |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn test_adding_peer_to_transport() { |
|
|
|
|
let mut transport = Transport::new(vec![Box::new(TestInterface::default())]); |
|
|
|
|
let (interface_id, interface_targeting_data) = ("test_interface".to_string(), "hi".to_string()); |
|
|
|
|
assert!(transport.get_peer_by_parameters(interface_id.as_str(), interface_targeting_data.as_str()).is_none()); |
|
|
|
|
let peer_id = transport.find_or_add_peer(interface_id.clone(), interface_targeting_data.clone()); |
|
|
|
|
let peer = PeerInfo { |
|
|
|
|
peer_id, |
|
|
|
|
interface_id: interface_id.clone(), |
|
|
|
|
interface_targeting_data: interface_targeting_data.clone(), |
|
|
|
|
}; |
|
|
|
|
assert_eq!(transport.get_peer_by_parameters(interface_id.as_str(), interface_targeting_data.as_str()), Some(&peer)); |
|
|
|
|
assert_eq!(transport.get_peer_by_id(peer_id), Some(peer)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn test_transport_sending() { |
|
|
|
|
let mut transport = Transport::new(vec![Box::new(TestInterface::default())]); |
|
|
|
|
let (interface_id, interface_targeting_data) = ("test_interface".to_string(), "hi".to_string()); |
|
|
|
|
let peer_id = transport.find_or_add_peer(interface_id.clone(), interface_targeting_data.clone()); |
|
|
|
|
transport.send_message(vec![239, 123], None).unwrap(); |
|
|
|
|
assert_eq!(transport.interfaces[0].receive().unwrap(), Some((vec![239u8, 123], "".to_string()))); |
|
|
|
|
assert!(transport.interfaces[0].receive() == IFResult::Ok(None)); |
|
|
|
|
transport.send_message(vec![239, 123], Some(peer_id)).unwrap(); |
|
|
|
|
assert_eq!(transport.interfaces[0].receive(), IFResult::Ok(Some((vec![239, 123], interface_targeting_data)))); |
|
|
|
|
} |
|
|
|
|