mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-23 14:51:34 +00:00
@ -51,16 +51,16 @@ impl<TProto1, TProto2> ProtocolsHandlerSelect<TProto1, TProto2> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSubstream, TProto1, TProto2, TProto1Out, TProto2Out>
|
impl<TSubstream, TProto1, TProto2>
|
||||||
ProtocolsHandler for ProtocolsHandlerSelect<TProto1, TProto2>
|
ProtocolsHandler for ProtocolsHandlerSelect<TProto1, TProto2>
|
||||||
where
|
where
|
||||||
TProto1: ProtocolsHandler<Substream = TSubstream>,
|
TProto1: ProtocolsHandler<Substream = TSubstream>,
|
||||||
TProto2: ProtocolsHandler<Substream = TSubstream>,
|
TProto2: ProtocolsHandler<Substream = TSubstream>,
|
||||||
TSubstream: AsyncRead + AsyncWrite,
|
TSubstream: AsyncRead + AsyncWrite,
|
||||||
TProto1::InboundProtocol: InboundUpgrade<TSubstream, Output = TProto1Out>,
|
TProto1::InboundProtocol: InboundUpgrade<TSubstream>,
|
||||||
TProto2::InboundProtocol: InboundUpgrade<TSubstream, Output = TProto2Out>,
|
TProto2::InboundProtocol: InboundUpgrade<TSubstream>,
|
||||||
TProto1::OutboundProtocol: OutboundUpgrade<TSubstream, Output = TProto1Out>,
|
TProto1::OutboundProtocol: OutboundUpgrade<TSubstream>,
|
||||||
TProto2::OutboundProtocol: OutboundUpgrade<TSubstream, Output = TProto2Out>
|
TProto2::OutboundProtocol: OutboundUpgrade<TSubstream>
|
||||||
{
|
{
|
||||||
type InEvent = EitherOutput<TProto1::InEvent, TProto2::InEvent>;
|
type InEvent = EitherOutput<TProto1::InEvent, TProto2::InEvent>;
|
||||||
type OutEvent = EitherOutput<TProto1::OutEvent, TProto2::OutEvent>;
|
type OutEvent = EitherOutput<TProto1::OutEvent, TProto2::OutEvent>;
|
||||||
|
@ -68,41 +68,26 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
|||||||
quote!{#n}
|
quote!{#n}
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_types = {
|
|
||||||
let mut start = 1;
|
|
||||||
// Avoid collisions.
|
|
||||||
while ast.generics.type_params().any(|tp| tp.ident.to_string() == format!("TOut{}", start)) {
|
|
||||||
start += 1;
|
|
||||||
}
|
|
||||||
data_struct.fields.iter()
|
|
||||||
.filter(|x| !is_ignored(x))
|
|
||||||
.enumerate()
|
|
||||||
.map(move |(i, _)| Ident::new(&format!("TOut{}", start + i), name.span()))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build the generics.
|
// Build the generics.
|
||||||
let impl_generics = {
|
let impl_generics = {
|
||||||
let tp = ast.generics.type_params();
|
let tp = ast.generics.type_params();
|
||||||
let lf = ast.generics.lifetimes();
|
let lf = ast.generics.lifetimes();
|
||||||
let cst = ast.generics.const_params();
|
let cst = ast.generics.const_params();
|
||||||
let out = output_types.clone();
|
quote!{<#(#lf,)* #(#tp,)* #(#cst,)* #substream_generic>}
|
||||||
quote!{<#(#lf,)* #(#tp,)* #(#cst,)* #substream_generic, #(#out),*>}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the `where ...` clause of the trait implementation.
|
// Build the `where ...` clause of the trait implementation.
|
||||||
let where_clause = {
|
let where_clause = {
|
||||||
let mut additional = data_struct.fields.iter()
|
let mut additional = data_struct.fields.iter()
|
||||||
.filter(|x| !is_ignored(x))
|
.filter(|x| !is_ignored(x))
|
||||||
.zip(output_types)
|
.flat_map(|field| {
|
||||||
.flat_map(|(field, out)| {
|
|
||||||
let ty = &field.ty;
|
let ty = &field.ty;
|
||||||
vec![
|
vec![
|
||||||
quote!{#ty: #trait_to_impl},
|
quote!{#ty: #trait_to_impl},
|
||||||
quote!{<#ty as #trait_to_impl>::ProtocolsHandler: #protocols_handler<Substream = #substream_generic>},
|
quote!{<#ty as #trait_to_impl>::ProtocolsHandler: #protocols_handler<Substream = #substream_generic>},
|
||||||
// Note: this bound is required because of https://github.com/rust-lang/rust/issues/55697
|
// Note: this bound is required because of https://github.com/rust-lang/rust/issues/55697
|
||||||
quote!{<<#ty as #trait_to_impl>::ProtocolsHandler as #protocols_handler>::InboundProtocol: ::libp2p::core::InboundUpgrade<#substream_generic, Output = #out>},
|
quote!{<<#ty as #trait_to_impl>::ProtocolsHandler as #protocols_handler>::InboundProtocol: ::libp2p::core::InboundUpgrade<#substream_generic>},
|
||||||
quote!{<<#ty as #trait_to_impl>::ProtocolsHandler as #protocols_handler>::OutboundProtocol: ::libp2p::core::OutboundUpgrade<#substream_generic, Output = #out>},
|
quote!{<<#ty as #trait_to_impl>::ProtocolsHandler as #protocols_handler>::OutboundProtocol: ::libp2p::core::OutboundUpgrade<#substream_generic>},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -21,6 +21,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate libp2p;
|
extern crate libp2p;
|
||||||
|
|
||||||
|
/// Small utility to check that a type implements `NetworkBehaviour`.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn require_net_behaviour<T: libp2p::core::swarm::NetworkBehaviour>() {}
|
||||||
|
|
||||||
// TODO: doesn't compile
|
// TODO: doesn't compile
|
||||||
/*#[test]
|
/*#[test]
|
||||||
fn empty() {
|
fn empty() {
|
||||||
@ -36,6 +40,10 @@ fn one_field() {
|
|||||||
struct Foo<TSubstream> {
|
struct Foo<TSubstream> {
|
||||||
ping: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
ping: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -55,29 +63,36 @@ fn three_fields() {
|
|||||||
struct Foo<TSubstream> {
|
struct Foo<TSubstream> {
|
||||||
ping_dialer: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
ping_dialer: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
||||||
ping_listener: libp2p::ping::PingListenBehaviour<TSubstream>,
|
ping_listener: libp2p::ping::PingListenBehaviour<TSubstream>,
|
||||||
identify: libp2p::identify::PeriodicIdentification<TSubstream>,
|
identify: libp2p::identify::PeriodicIdentifyBehaviour<TSubstream>,
|
||||||
#[behaviour(ignore)]
|
#[behaviour(ignore)]
|
||||||
foo: String,
|
foo: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn event_handler() {
|
fn event_handler() {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(NetworkBehaviour)]
|
#[derive(NetworkBehaviour)]
|
||||||
// TODO: remove the generics requirements once identify no longer requires them
|
struct Foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite> {
|
||||||
struct Foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite + Send + Sync + 'static> {
|
|
||||||
#[behaviour(handler = "foo")]
|
#[behaviour(handler = "foo")]
|
||||||
identify: libp2p::identify::PeriodicIdentifyBehaviour<TSubstream>,
|
identify: libp2p::identify::PeriodicIdentifyBehaviour<TSubstream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite + Send + Sync + 'static> Foo<TSubstream> {
|
impl<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite> Foo<TSubstream> {
|
||||||
// TODO: for some reason, the parameter cannot be `PeriodicIdentifyBehaviourEvent` or we
|
// TODO: for some reason, the parameter cannot be `PeriodicIdentifyBehaviourEvent` or we
|
||||||
// get a compilation error ; figure out why or open an issue to Rust
|
// get a compilation error ; figure out why or open an issue to Rust
|
||||||
fn foo(&mut self, ev: <libp2p::identify::PeriodicIdentifyBehaviour<TSubstream> as libp2p::core::swarm::NetworkBehaviour>::OutEvent) {
|
fn foo(&mut self, ev: <libp2p::identify::PeriodicIdentifyBehaviour<TSubstream> as libp2p::core::swarm::NetworkBehaviour>::OutEvent) {
|
||||||
let libp2p::identify::PeriodicIdentifyBehaviourEvent::Identified { .. } = ev;
|
let libp2p::identify::PeriodicIdentifyBehaviourEvent::Identified { .. } = ev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -93,6 +108,10 @@ fn custom_polling() {
|
|||||||
impl<TSubstream> Foo<TSubstream> {
|
impl<TSubstream> Foo<TSubstream> {
|
||||||
fn foo<T>(&mut self) -> libp2p::futures::Async<libp2p::core::swarm::NetworkBehaviourAction<T, ()>> { libp2p::futures::Async::NotReady }
|
fn foo<T>(&mut self) -> libp2p::futures::Async<libp2p::core::swarm::NetworkBehaviourAction<T, ()>> { libp2p::futures::Async::NotReady }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -104,6 +123,10 @@ fn custom_event_no_polling() {
|
|||||||
ping: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
ping: libp2p::ping::PeriodicPingBehaviour<TSubstream>,
|
||||||
identify: libp2p::identify::PeriodicIdentifyBehaviour<TSubstream>,
|
identify: libp2p::identify::PeriodicIdentifyBehaviour<TSubstream>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -119,4 +142,8 @@ fn custom_event_and_polling() {
|
|||||||
impl<TSubstream> Foo<TSubstream> {
|
impl<TSubstream> Foo<TSubstream> {
|
||||||
fn foo<T>(&mut self) -> libp2p::futures::Async<libp2p::core::swarm::NetworkBehaviourAction<T, String>> { libp2p::futures::Async::NotReady }
|
fn foo<T>(&mut self) -> libp2p::futures::Async<libp2p::core::swarm::NetworkBehaviourAction<T, String>> { libp2p::futures::Async::NotReady }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo<TSubstream: libp2p::tokio_io::AsyncRead + libp2p::tokio_io::AsyncWrite>() {
|
||||||
|
require_net_behaviour::<Foo<TSubstream>>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user