Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swarm/src/either: implement NetworkBehaviour on Either #2370

Merged
merged 8 commits into from
Dec 12, 2021
Merged
1 change: 1 addition & 0 deletions swarm-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ quote = "1.0"

[dev-dependencies]
libp2p = { path = "../" }
either = "1.6.0"
futures = "0.3.1"
98 changes: 98 additions & 0 deletions swarm-derive/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,101 @@ fn event_process_false() {
};
}
}

#[test]
fn with_toggle() {
mexskican marked this conversation as resolved.
Show resolved Hide resolved
use libp2p::swarm::toggle::Toggle;

#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(event_process = true)]
struct Foo {
indentify: libp2p::identify::Identify,
mexskican marked this conversation as resolved.
Show resolved Hide resolved
ping: Toggle<libp2p::ping::Ping>,
}

impl libp2p::swarm::NetworkBehaviourEventProcess<libp2p::identify::IdentifyEvent> for Foo {
fn inject_event(&mut self, _: libp2p::identify::IdentifyEvent) {}
}

impl libp2p::swarm::NetworkBehaviourEventProcess<libp2p::ping::PingEvent> for Foo {
fn inject_event(&mut self, _: libp2p::ping::PingEvent) {}
}

#[allow(dead_code)]
fn foo() {
require_net_behaviour::<Foo>();
}
}

#[test]
fn with_either() {
use either::Either;

#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(event_process = true)]
struct Foo {
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
ping_or_identify: Either<libp2p::ping::Ping, libp2p::identify::Identify>,
}

impl libp2p::swarm::NetworkBehaviourEventProcess<libp2p::kad::KademliaEvent> for Foo {
fn inject_event(&mut self, _: libp2p::kad::KademliaEvent) {}
}

impl
libp2p::swarm::NetworkBehaviourEventProcess<
Either<libp2p::ping::PingEvent, libp2p::identify::IdentifyEvent>,
> for Foo
{
fn inject_event(
&mut self,
_: Either<libp2p::ping::PingEvent, libp2p::identify::IdentifyEvent>,
) {
}
}

#[allow(dead_code)]
fn foo() {
require_net_behaviour::<Foo>();
}
}

#[test]
fn no_event_with_either() {
use either::Either;

enum BehaviourOutEvent {
Kad(libp2p::kad::KademliaEvent),
PingOrIdentify(Either<libp2p::ping::PingEvent, libp2p::identify::IdentifyEvent>),
}

#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "BehaviourOutEvent", event_process = false)]
struct Foo {
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
ping_or_identify: Either<libp2p::ping::Ping, libp2p::identify::Identify>,
}

impl From<libp2p::kad::KademliaEvent> for BehaviourOutEvent {
fn from(event: libp2p::kad::KademliaEvent) -> Self {
BehaviourOutEvent::Kad(event)
}
}

impl From<Either<libp2p::ping::PingEvent, libp2p::identify::IdentifyEvent>> for BehaviourOutEvent {
fn from(event: Either<libp2p::ping::PingEvent, libp2p::identify::IdentifyEvent>) -> Self {
match event {
Either::Left(event) => BehaviourOutEvent::PingOrIdentify(Either::Left(event)),
Either::Right(event) => BehaviourOutEvent::PingOrIdentify(Either::Right(event)),
}
mexskican marked this conversation as resolved.
Show resolved Hide resolved
}
}

#[allow(dead_code)]
fn foo() {
require_net_behaviour::<Foo>();
}
}
44 changes: 44 additions & 0 deletions swarm/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,50 @@ where
}
}

impl<TInEventOld, TOutEvent, THandlerOld> NetworkBehaviourAction<TOutEvent, THandlerOld>
where
THandlerOld: IntoProtocolsHandler,
<THandlerOld as IntoProtocolsHandler>::Handler: ProtocolsHandler<InEvent = TInEventOld>,
{
/// Map the handler and hanlder event
mexskican marked this conversation as resolved.
Show resolved Hide resolved
pub fn map_handler_and_in_event<THandlerNew, TInEventNew>(
mexskican marked this conversation as resolved.
Show resolved Hide resolved
self,
f_handler: impl FnOnce(THandlerOld) -> THandlerNew,
f_in_event: impl FnOnce(TInEventOld) -> TInEventNew,
) -> NetworkBehaviourAction<TOutEvent, THandlerNew>
where
THandlerNew: IntoProtocolsHandler,
<THandlerNew as IntoProtocolsHandler>::Handler: ProtocolsHandler<InEvent = TInEventNew>,
{
match self {
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e),
NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial {
opts,
handler: f_handler(handler),
},
NetworkBehaviourAction::NotifyHandler {
peer_id,
handler,
event,
} => NetworkBehaviourAction::NotifyHandler {
peer_id,
handler,
event: f_in_event(event),
},
NetworkBehaviourAction::ReportObservedAddr { address, score } => {
NetworkBehaviourAction::ReportObservedAddr { address, score }
}
NetworkBehaviourAction::CloseConnection {
peer_id,
connection,
} => NetworkBehaviourAction::CloseConnection {
peer_id,
connection,
},
}
}
}

/// The options w.r.t. which connection handler to notify of an event.
#[derive(Debug, Clone)]
pub enum NotifyHandler {
Expand Down
Loading