swarm-derive: Add prelude configuration option to NetworkBehaviour macro (#3055)

Currently, our `NetworkBehaviour` derive macro depends on the `libp2p` crate to be in scope. This prevents standalone usage which forces us to depend on `libp2p` in all our tests where we want to derive a `NetworkBehaviour`.

This PR introduces a `prelude` option that - by default - points to `libp2p::swarm::derive_prelude`, a new module added to `libp2p_swarm`. With this config option, users of `libp2p_swarm` can now refer to the macro without depending on `libp2p`, breaking the circular dependency in our workspace. For consistency with the ecosystem, the macro is now also re-exported by `libp2p_swarm` instead of `libp2p` at the same position as the trait that it implements.

Lastly, we introduce an off-by-default `macros` feature flag that shrinks the dependency tree for users that don't need the derive macro.
This commit is contained in:
Thomas Eizinger
2022-11-13 10:59:14 +11:00
committed by GitHub
parent c32f03c317
commit afb777e937
31 changed files with 211 additions and 132 deletions

View File

@ -50,6 +50,9 @@
- Remove deprecated features: `tcp-tokio`, `mdns-tokio`, `dns-tokio`, `tcp-async-io`, `mdns-async-io`, `dns-async-std`.
See [PR 3001].
- Introduce [`libp2p-tls` `v0.1.0`](transports/tls/CHANGELOG.md#010). See [PR 2945].
- Remove `NetworkBehaviour` macro export from root crate in favor of re-exported macro from `libp2p::swarm`.
Change your import from `libp2p::NetworkBehaviour` to `libp2p::swarm::NetworkBehaviour`. See [PR 3055].
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
- Update individual crates.
- Update to [`libp2p-autonat` `v0.89.0`](protocols/autonat/CHANGELOG.md#090).
- Update to [`libp2p-core` `v0.38.0`](core/CHANGELOG.md#0380).
@ -79,6 +82,7 @@
[PR 2945]: https://github.com/libp2p/rust-libp2p/pull/2945
[PR 3001]: https://github.com/libp2p/rust-libp2p/pull/3001
[PR 2945]: https://github.com/libp2p/rust-libp2p/pull/2945
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
# 0.49.0

View File

@ -29,6 +29,7 @@ full = [
"ping",
"plaintext",
"pnet",
"macros",
"relay",
"rendezvous",
"request-response",
@ -45,38 +46,39 @@ full = [
"websocket",
"yamux",
]
async-std = ["libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std"]
autonat = ["dep:libp2p-autonat"]
dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"]
deflate = ["dep:libp2p-deflate"]
dns = ["dep:libp2p-dns"]
ecdsa = ["libp2p-core/ecdsa"]
floodsub = ["dep:libp2p-floodsub"]
gossipsub = ["dep:libp2p-gossipsub", "libp2p-metrics?/gossipsub"]
identify = ["dep:libp2p-identify", "libp2p-metrics?/identify"]
kad = ["dep:libp2p-kad", "libp2p-metrics?/kad"]
gossipsub = ["dep:libp2p-gossipsub", "libp2p-metrics?/gossipsub"]
macros = ["libp2p-swarm/macros"]
mdns = ["dep:libp2p-mdns"]
tls = ["dep:libp2p-tls"]
metrics = ["dep:libp2p-metrics"]
mdns = ["dep:libp2p-mdns"]
mplex = ["dep:libp2p-mplex"]
noise = ["dep:libp2p-noise"]
ping = ["dep:libp2p-ping", "libp2p-metrics?/ping"]
plaintext = ["dep:libp2p-plaintext"]
pnet = ["dep:libp2p-pnet"]
relay = ["dep:libp2p-relay", "libp2p-metrics?/relay"]
request-response = ["dep:libp2p-request-response"]
rendezvous = ["dep:libp2p-rendezvous"]
request-response = ["dep:libp2p-request-response"]
rsa = ["libp2p-core/rsa"]
secp256k1 = ["libp2p-core/secp256k1"]
serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"]
tcp = ["dep:libp2p-tcp"]
tokio = ["libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio"]
uds = ["dep:libp2p-uds"]
wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js"]
wasm-ext = ["dep:libp2p-wasm-ext"]
wasm-ext-websocket = ["wasm-ext", "libp2p-wasm-ext?/websocket"]
websocket = ["dep:libp2p-websocket"]
yamux = ["dep:libp2p-yamux"]
secp256k1 = ["libp2p-core/secp256k1"]
rsa = ["libp2p-core/rsa"]
ecdsa = ["libp2p-core/ecdsa"]
serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"]
tokio = ["libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio"]
async-std = ["libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std"]
[dependencies]
bytes = "1"
@ -102,7 +104,6 @@ libp2p-relay = { version = "0.14.0", path = "protocols/relay", optional = true }
libp2p-rendezvous = { version = "0.11.0", path = "protocols/rendezvous", optional = true }
libp2p-request-response = { version = "0.23.0", path = "protocols/request-response", optional = true }
libp2p-swarm = { version = "0.41.0", path = "swarm" }
libp2p-swarm-derive = { version = "0.30.1", path = "swarm-derive" }
libp2p-uds = { version = "0.37.0", path = "transports/uds", optional = true }
libp2p-wasm-ext = { version = "0.38.0", path = "transports/wasm-ext", optional = true }
libp2p-yamux = { version = "0.42.0", path = "muxers/yamux", optional = true }

View File

@ -39,8 +39,8 @@ use libp2p::{
TokioMdns,
},
mplex, noise,
swarm::{SwarmBuilder, SwarmEvent},
tcp, Multiaddr, NetworkBehaviour, PeerId, Transport,
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
tcp, Multiaddr, PeerId, Transport,
};
use std::error::Error;
use tokio::io::{self, AsyncBufReadExt};

View File

@ -58,8 +58,8 @@ use libp2p::{
floodsub::{self, Floodsub, FloodsubEvent},
identity,
mdns::{Mdns, MdnsConfig, MdnsEvent},
swarm::SwarmEvent,
Multiaddr, NetworkBehaviour, PeerId, Swarm,
swarm::{NetworkBehaviour, SwarmEvent},
Multiaddr, PeerId, Swarm,
};
use std::error::Error;

View File

@ -50,8 +50,8 @@ use libp2p::kad::{
use libp2p::{
development_transport, identity,
mdns::{Mdns, MdnsConfig, MdnsEvent},
swarm::SwarmEvent,
NetworkBehaviour, PeerId, Swarm,
swarm::{NetworkBehaviour, SwarmEvent},
PeerId, Swarm,
};
use std::error::Error;

View File

@ -219,8 +219,9 @@ mod network {
ProtocolSupport, RequestId, RequestResponse, RequestResponseCodec, RequestResponseEvent,
RequestResponseMessage, ResponseChannel,
};
use libp2p::swarm::{ConnectionHandlerUpgrErr, SwarmBuilder, SwarmEvent};
use libp2p::{NetworkBehaviour, Swarm};
use libp2p::swarm::{
ConnectionHandlerUpgrErr, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent,
};
use std::collections::{hash_map, HashMap, HashSet};
use std::iter;

View File

@ -55,8 +55,9 @@ use libp2p::gossipsub::{
use libp2p::{
gossipsub, identity,
mdns::{Mdns, MdnsConfig, MdnsEvent},
swarm::NetworkBehaviour,
swarm::SwarmEvent,
NetworkBehaviour, PeerId, Swarm,
PeerId, Swarm,
};
use std::collections::hash_map::DefaultHasher;
use std::error::Error;

View File

@ -42,10 +42,10 @@ use libp2p::{
multiaddr::Protocol,
noise, ping,
pnet::{PnetConfig, PreSharedKey},
swarm::SwarmEvent,
swarm::{NetworkBehaviour, SwarmEvent},
tcp,
yamux::YamuxConfig,
Multiaddr, NetworkBehaviour, PeerId, Swarm, Transport,
Multiaddr, PeerId, Swarm, Transport,
};
use std::{env, error::Error, fs, path::Path, str::FromStr, time::Duration};

View File

@ -41,8 +41,8 @@
//! and begin pinging each other.
use futures::prelude::*;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, ping, Multiaddr, NetworkBehaviour, PeerId};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::{identity, ping, Multiaddr, PeerId};
use libp2p_swarm::keep_alive;
use std::error::Error;

View File

@ -53,8 +53,8 @@ use futures::executor::block_on;
use futures::stream::StreamExt;
use libp2p::core::Multiaddr;
use libp2p::metrics::{Metrics, Recorder};
use libp2p::swarm::SwarmEvent;
use libp2p::{identity, ping, NetworkBehaviour, PeerId, Swarm};
use libp2p::swarm::{NetworkBehaviour, SwarmEvent};
use libp2p::{identity, ping, PeerId, Swarm};
use libp2p_swarm::keep_alive;
use log::info;
use prometheus_client::registry::Registry;

View File

@ -34,8 +34,8 @@ use futures::prelude::*;
use libp2p::autonat;
use libp2p::identify;
use libp2p::multiaddr::Protocol;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, NetworkBehaviour, PeerId};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, PeerId};
use std::error::Error;
use std::net::Ipv4Addr;
use std::time::Duration;

View File

@ -31,8 +31,8 @@ use futures::prelude::*;
use libp2p::autonat;
use libp2p::identify;
use libp2p::multiaddr::Protocol;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, NetworkBehaviour, PeerId};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::{identity, Multiaddr, PeerId};
use std::error::Error;
use std::net::Ipv4Addr;

View File

@ -29,11 +29,11 @@ use libp2p::dns::DnsConfig;
use libp2p::identify;
use libp2p::noise;
use libp2p::relay::v2::client::{self, Client};
use libp2p::swarm::{SwarmBuilder, SwarmEvent};
use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent};
use libp2p::tcp;
use libp2p::Transport;
use libp2p::{dcutr, ping};
use libp2p::{identity, NetworkBehaviour, PeerId};
use libp2p::{identity, PeerId};
use log::info;
use std::convert::TryInto;
use std::error::Error;

View File

@ -34,7 +34,6 @@ use libp2p::plaintext::PlainText2Config;
use libp2p::relay::v2::client;
use libp2p::relay::v2::relay;
use libp2p::swarm::{AddressScore, NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::NetworkBehaviour;
use std::time::Duration;
#[test]

View File

@ -30,10 +30,9 @@ use libp2p::core::{
use libp2p::mplex;
use libp2p::noise;
use libp2p::ping;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::tcp;
use libp2p::yamux;
use libp2p::NetworkBehaviour;
use libp2p_swarm::keep_alive;
use quickcheck::*;
use std::{num::NonZeroU8, time::Duration};

View File

@ -27,10 +27,10 @@ use libp2p::identify;
use libp2p::multiaddr::Protocol;
use libp2p::ping;
use libp2p::relay::v2::relay::{self, Relay};
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::tcp;
use libp2p::Transport;
use libp2p::{identity, NetworkBehaviour, PeerId};
use libp2p::{identity, PeerId};
use libp2p::{noise, Multiaddr};
use std::error::Error;
use std::net::{Ipv4Addr, Ipv6Addr};

View File

@ -29,11 +29,11 @@ use libp2p::core::transport::choice::OrTransport;
use libp2p::core::transport::{Boxed, MemoryTransport, Transport};
use libp2p::core::PublicKey;
use libp2p::core::{identity, upgrade, PeerId};
use libp2p::ping;
use libp2p::plaintext::PlainText2Config;
use libp2p::relay::v2::client;
use libp2p::relay::v2::relay;
use libp2p::swarm::{AddressScore, NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::{ping, NetworkBehaviour};
use std::time::Duration;
#[test]

View File

@ -143,7 +143,7 @@ impl From<Void> for MyEvent {
}
}
#[derive(libp2p::NetworkBehaviour)]
#[derive(libp2p::swarm::NetworkBehaviour)]
#[behaviour(event_process = false)]
#[behaviour(out_event = "MyEvent")]
struct MyBehaviour {

View File

@ -22,9 +22,9 @@ use futures::StreamExt;
use libp2p::core::identity;
use libp2p::core::PeerId;
use libp2p::ping;
use libp2p::swarm::{Swarm, SwarmEvent};
use libp2p::swarm::{NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::Multiaddr;
use libp2p::{development_transport, rendezvous};
use libp2p::{Multiaddr, NetworkBehaviour};
use libp2p_swarm::AddressScore;
use std::time::Duration;

View File

@ -23,9 +23,9 @@ use libp2p::core::identity;
use libp2p::core::PeerId;
use libp2p::identify;
use libp2p::ping;
use libp2p::swarm::{keep_alive, Swarm, SwarmEvent};
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::Multiaddr;
use libp2p::{development_transport, rendezvous};
use libp2p::{Multiaddr, NetworkBehaviour};
use std::time::Duration;
use void::Void;

View File

@ -23,8 +23,7 @@ use libp2p::core::identity;
use libp2p::core::PeerId;
use libp2p::identify;
use libp2p::ping;
use libp2p::swarm::{keep_alive, Swarm, SwarmEvent};
use libp2p::NetworkBehaviour;
use libp2p::swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmEvent};
use libp2p::{development_transport, rendezvous};
use void::Void;

View File

@ -366,7 +366,7 @@ async fn new_impersonating_client() -> Swarm<rendezvous::client::Behaviour> {
eve
}
#[derive(libp2p::NetworkBehaviour)]
#[derive(libp2p::swarm::NetworkBehaviour)]
#[behaviour(event_process = false, out_event = "CombinedEvent")]
struct CombinedBehaviour {
client: rendezvous::client::Behaviour,

View File

@ -145,7 +145,6 @@ pub use self::multiaddr::{multiaddr as build_multiaddr, Multiaddr};
pub use self::simple::SimpleProtocol;
pub use self::swarm::Swarm;
pub use self::transport_ext::TransportExt;
pub use libp2p_swarm_derive::NetworkBehaviour;
/// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p:
///

View File

@ -1,3 +1,10 @@
# 0.30.2 [unreleased]
- Add `prelude` configuration option.
The derive-macro generates code that needs to refer to various symbols. See [PR 3055].
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
# 0.30.1
- Fix an issue where the derive would generate bad code if the type parameters between the behaviour and a custom

View File

@ -3,7 +3,7 @@ name = "libp2p-swarm-derive"
edition = "2021"
rust-version = "1.56.1"
description = "Procedural macros of libp2p-core"
version = "0.30.1"
version = "0.30.2"
authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
@ -18,12 +18,6 @@ heck = "0.4"
quote = "1.0"
syn = { version = "1.0.8", default-features = false, features = ["clone-impls", "derive", "parsing", "printing", "proc-macro"] }
[dev-dependencies]
libp2p = { path = "..", features = ["full"] }
either = "1.6.0"
futures = "0.3.1"
void = "1"
# Passing arguments to the docsrs builder in order to properly document cfg's.
# More information: https://docs.rs/about/builds#cross-compiling
[package.metadata.docs.rs]

View File

@ -24,6 +24,7 @@
use heck::ToUpperCamelCase;
use proc_macro::TokenStream;
use quote::quote;
use syn::parse::Parse;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput};
/// Generates a delegating `NetworkBehaviour` implementation for the struct this is used for. See
@ -47,21 +48,24 @@ fn build(ast: &DeriveInput) -> TokenStream {
fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let name = &ast.ident;
let (_, ty_generics, where_clause) = ast.generics.split_for_impl();
let multiaddr = quote! {::libp2p::core::Multiaddr};
let trait_to_impl = quote! {::libp2p::swarm::NetworkBehaviour};
let either_ident = quote! {::libp2p::core::either::EitherOutput};
let network_behaviour_action = quote! {::libp2p::swarm::NetworkBehaviourAction};
let into_connection_handler = quote! {::libp2p::swarm::IntoConnectionHandler};
let connection_handler = quote! {::libp2p::swarm::ConnectionHandler};
let into_proto_select_ident = quote! {::libp2p::swarm::IntoConnectionHandlerSelect};
let peer_id = quote! {::libp2p::core::PeerId};
let connection_id = quote! {::libp2p::core::connection::ConnectionId};
let dial_errors = quote! {Option<&Vec<::libp2p::core::Multiaddr>>};
let connected_point = quote! {::libp2p::core::ConnectedPoint};
let listener_id = quote! {::libp2p::core::transport::ListenerId};
let dial_error = quote! {::libp2p::swarm::DialError};
let poll_parameters = quote! {::libp2p::swarm::PollParameters};
let prelude_path = parse_attribute_value_by_key::<syn::Path>(ast, "prelude")
.unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude });
let multiaddr = quote! { #prelude_path::Multiaddr };
let trait_to_impl = quote! { #prelude_path::NetworkBehaviour };
let either_ident = quote! { #prelude_path::EitherOutput };
let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction };
let into_connection_handler = quote! { #prelude_path::IntoConnectionHandler };
let connection_handler = quote! { #prelude_path::ConnectionHandler };
let into_proto_select_ident = quote! { #prelude_path::IntoConnectionHandlerSelect };
let peer_id = quote! { #prelude_path::PeerId };
let connection_id = quote! { #prelude_path::ConnectionId };
let dial_errors = quote! {Option<&Vec<#prelude_path::Multiaddr>> };
let connected_point = quote! { #prelude_path::ConnectedPoint };
let listener_id = quote! { #prelude_path::ListenerId };
let dial_error = quote! { #prelude_path::DialError };
let poll_parameters = quote! { #prelude_path::PollParameters };
// Build the generics.
let impl_generics = {
@ -75,22 +79,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// If we find a `#[behaviour(out_event = "Foo")]` attribute on the
// struct, we set `Foo` as the out event. If not, the `OutEvent` is
// generated.
let user_provided_out_event_name: Option<syn::Type> = ast
.attrs
.iter()
.filter_map(get_meta_items)
.flatten()
.filter_map(|meta_item| {
if let syn::NestedMeta::Meta(syn::Meta::NameValue(ref m)) = meta_item {
if m.path.is_ident("out_event") {
if let syn::Lit::Str(ref s) = m.lit {
return Some(syn::parse_str(&s.value()).unwrap());
}
}
}
None
})
.next();
let user_provided_out_event_name =
parse_attribute_value_by_key::<syn::Type>(ast, "out_event");
match user_provided_out_event_name {
// User provided `OutEvent`.
@ -625,7 +615,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
}
fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action<Self::OutEvent, Self::ConnectionHandler>> {
use libp2p::futures::prelude::*;
use #prelude_path::futures::*;
#(#poll_stmts)*
std::task::Poll::Pending
}
@ -635,6 +625,30 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
final_quote.into()
}
/// Parses the `value` of a key=value pair in the `#[behaviour]` attribute into the requested type.
///
/// Only `String` values are supported, e.g. `#[behaviour(foo="bar")]`.
fn parse_attribute_value_by_key<T>(ast: &DeriveInput, key: &str) -> Option<T>
where
T: Parse,
{
ast.attrs
.iter()
.filter_map(get_meta_items)
.flatten()
.filter_map(|meta_item| {
if let syn::NestedMeta::Meta(syn::Meta::NameValue(ref m)) = meta_item {
if m.path.is_ident(key) {
if let syn::Lit::Str(ref s) = m.lit {
return Some(syn::parse_str(&s.value()).unwrap());
}
}
}
None
})
.next()
}
fn get_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMeta>> {
if attr.path.segments.len() == 1 && attr.path.segments[0].ident == "behaviour" {
match attr.parse_meta() {

View File

@ -2,6 +2,13 @@
- Update to `libp2p-core` `v0.38.0`.
- Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`.
This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as
`serde::Serialize`. See [PR 3055].
- Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055].
[PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055
# 0.40.1
- Bump rand to 0.8 and quickcheck to 1. See [PR 2857].

View File

@ -17,6 +17,7 @@ futures = "0.3.1"
futures-timer = "3.0.2"
instant = "0.1.11"
libp2p-core = { version = "0.38.0", path = "../core" }
libp2p-swarm-derive = { version = "0.30.2", path = "../swarm-derive", optional = true }
log = "0.4"
pin-project = "1.0.0"
rand = "0.8"
@ -24,11 +25,26 @@ smallvec = "1.6.1"
thiserror = "1.0"
void = "1"
[features]
macros = ["dep:libp2p-swarm-derive"]
[dev-dependencies]
async-std = { version = "1.6.2", features = ["attributes"] }
either = "1.6.0"
env_logger = "0.9"
libp2p = { path = "..", features = ["full"] }
futures = "0.3.1"
libp2p-identify = { path = "../protocols/identify" }
libp2p-kad = { path = "../protocols/kad" }
libp2p-ping = { path = "../protocols/ping" }
libp2p-plaintext = { path = "../transports/plaintext" }
libp2p-swarm-derive = { version = "0.30.2", path = "../swarm-derive" }
libp2p-yamux = { path = "../muxers/yamux" }
quickcheck = { package = "quickcheck-ext", path = "../misc/quickcheck-ext" }
void = "1"
[[test]]
name = "swarm_derive"
required-features = ["macros"]
# Passing arguments to the docsrs builder in order to properly document cfg's.
# More information: https://docs.rs/about/builds#cross-compiling

View File

@ -90,11 +90,12 @@ pub(crate) type THandlerOutEvent<THandler> =
/// addition to the event `enum` itself.
///
/// ``` rust
/// # use libp2p::identify;
/// # use libp2p::ping;
/// # use libp2p::NetworkBehaviour;
/// # use libp2p_identify as identify;
/// # use libp2p_ping as ping;
/// # use libp2p_swarm_derive::NetworkBehaviour;
/// #[derive(NetworkBehaviour)]
/// #[behaviour(out_event = "Event")]
/// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")]
/// struct MyBehaviour {
/// identify: identify::Behaviour,
/// ping: ping::Behaviour,
@ -315,19 +316,19 @@ pub enum NetworkBehaviourAction<
/// ```rust
/// # use futures::executor::block_on;
/// # use futures::stream::StreamExt;
/// # use libp2p::core::connection::ConnectionId;
/// # use libp2p::core::identity;
/// # use libp2p::core::transport::{MemoryTransport, Transport};
/// # use libp2p::core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade};
/// # use libp2p::core::PeerId;
/// # use libp2p::plaintext::PlainText2Config;
/// # use libp2p::swarm::{
/// # use libp2p_core::connection::ConnectionId;
/// # use libp2p_core::identity;
/// # use libp2p_core::transport::{MemoryTransport, Transport};
/// # use libp2p_core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade};
/// # use libp2p_core::PeerId;
/// # use libp2p_plaintext::PlainText2Config;
/// # use libp2p_swarm::{
/// # DialError, IntoConnectionHandler, KeepAlive, NegotiatedSubstream,
/// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectionHandler,
/// # ConnectionHandlerEvent, ConnectionHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent,
/// # };
/// # use libp2p::swarm::dial_opts::{DialOpts, PeerCondition};
/// # use libp2p::yamux;
/// # use libp2p_swarm::dial_opts::{DialOpts, PeerCondition};
/// # use libp2p_yamux as yamux;
/// # use std::collections::VecDeque;
/// # use std::task::{Context, Poll};
/// # use void::Void;

View File

@ -67,6 +67,25 @@ pub mod dummy;
pub mod handler;
pub mod keep_alive;
/// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro.
#[doc(hidden)]
pub mod derive_prelude {
pub use crate::ConnectionHandler;
pub use crate::DialError;
pub use crate::IntoConnectionHandler;
pub use crate::IntoConnectionHandlerSelect;
pub use crate::NetworkBehaviour;
pub use crate::NetworkBehaviourAction;
pub use crate::PollParameters;
pub use futures::prelude as futures;
pub use libp2p_core::connection::ConnectionId;
pub use libp2p_core::either::EitherOutput;
pub use libp2p_core::transport::ListenerId;
pub use libp2p_core::ConnectedPoint;
pub use libp2p_core::Multiaddr;
pub use libp2p_core::PeerId;
}
pub use behaviour::{
CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters,
};
@ -80,6 +99,8 @@ pub use handler::{
IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler,
OneShotHandlerConfig, SubstreamProtocol,
};
#[cfg(feature = "macros")]
pub use libp2p_swarm_derive::NetworkBehaviour;
pub use registry::{AddAddressResult, AddressRecord, AddressScore};
use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent};
@ -1568,12 +1589,12 @@ mod tests {
use futures::future::poll_fn;
use futures::future::Either;
use futures::{executor, future, ready};
use libp2p::core::{identity, multiaddr, transport, upgrade};
use libp2p::plaintext;
use libp2p::yamux;
use libp2p_core::multiaddr::multiaddr;
use libp2p_core::transport::TransportEvent;
use libp2p_core::Endpoint;
use libp2p_core::{identity, multiaddr, transport, upgrade};
use libp2p_plaintext as plaintext;
use libp2p_yamux as yamux;
use quickcheck::*;
// Test execution state.

View File

@ -18,15 +18,15 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use futures::prelude::*;
use libp2p::swarm::{dummy, NetworkBehaviour, SwarmEvent};
use libp2p::{identify, ping};
use libp2p_swarm_derive::*;
use futures::StreamExt;
use libp2p_identify as identify;
use libp2p_ping as ping;
use libp2p_swarm::{dummy, NetworkBehaviour, SwarmEvent};
use std::fmt::Debug;
/// Small utility to check that a type implements `NetworkBehaviour`.
#[allow(dead_code)]
fn require_net_behaviour<T: libp2p::swarm::NetworkBehaviour>() {}
fn require_net_behaviour<T: libp2p_swarm::NetworkBehaviour>() {}
// TODO: doesn't compile
/*#[test]
@ -40,6 +40,7 @@ fn empty() {
fn one_field() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
}
@ -57,6 +58,7 @@ fn one_field() {
fn two_fields() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
identify: identify::Behaviour,
@ -78,10 +80,11 @@ fn two_fields() {
fn three_fields() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
identify: identify::Behaviour,
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
kad: libp2p_kad::Kademlia<libp2p_kad::record::store::MemoryStore>,
}
#[allow(dead_code, unreachable_code, clippy::diverging_sub_expression)]
@ -93,7 +96,7 @@ fn three_fields() {
let _: identify::Event = event;
}
FooEvent::Kad(event) => {
let _: libp2p::kad::KademliaEvent = event;
let _: libp2p_kad::KademliaEvent = event;
}
}
}
@ -103,7 +106,7 @@ fn three_fields() {
fn custom_event() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "MyEvent")]
#[behaviour(out_event = "MyEvent", prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
identify: identify::Behaviour,
@ -121,8 +124,8 @@ fn custom_event() {
}
}
impl From<libp2p::identify::Event> for MyEvent {
fn from(event: libp2p::identify::Event) -> Self {
impl From<identify::Event> for MyEvent {
fn from(event: identify::Event) -> Self {
MyEvent::Identify(event)
}
}
@ -137,16 +140,16 @@ fn custom_event() {
fn custom_event_mismatching_field_names() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "MyEvent")]
#[behaviour(out_event = "MyEvent", prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
a: ping::Behaviour,
b: libp2p::identify::Behaviour,
b: identify::Behaviour,
}
#[allow(clippy::large_enum_variant)]
enum MyEvent {
Ping(ping::Event),
Identify(libp2p::identify::Event),
Identify(identify::Event),
}
impl From<ping::Event> for MyEvent {
@ -155,8 +158,8 @@ fn custom_event_mismatching_field_names() {
}
}
impl From<libp2p::identify::Event> for MyEvent {
fn from(event: libp2p::identify::Event) -> Self {
impl From<identify::Event> for MyEvent {
fn from(event: identify::Event) -> Self {
MyEvent::Identify(event)
}
}
@ -171,6 +174,7 @@ fn custom_event_mismatching_field_names() {
fn bound() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo<T: Copy + NetworkBehaviour>
where
<T as NetworkBehaviour>::OutEvent: Debug,
@ -184,6 +188,7 @@ fn bound() {
fn where_clause() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo<T>
where
T: Copy + NetworkBehaviour,
@ -198,12 +203,14 @@ fn where_clause() {
fn nested_derives_with_import() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
}
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Bar {
foo: Foo,
}
@ -231,15 +238,18 @@ fn custom_event_emit_event_through_poll() {
}
}
impl From<libp2p::identify::Event> for BehaviourOutEvent {
fn from(event: libp2p::identify::Event) -> Self {
impl From<identify::Event> for BehaviourOutEvent {
fn from(event: identify::Event) -> Self {
BehaviourOutEvent::Identify(event)
}
}
#[allow(dead_code, clippy::large_enum_variant)]
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "BehaviourOutEvent")]
#[behaviour(
out_event = "BehaviourOutEvent",
prelude = "libp2p_swarm::derive_prelude"
)]
struct Foo {
ping: ping::Behaviour,
identify: identify::Behaviour,
@ -249,7 +259,7 @@ fn custom_event_emit_event_through_poll() {
fn bar() {
require_net_behaviour::<Foo>();
let mut _swarm: libp2p::Swarm<Foo> = unimplemented!();
let mut _swarm: libp2p_swarm::Swarm<Foo> = unimplemented!();
// check that the event is bubbled up all the way to swarm
let _ = async {
@ -266,10 +276,11 @@ fn custom_event_emit_event_through_poll() {
#[test]
fn with_toggle() {
use libp2p::swarm::behaviour::toggle::Toggle;
use libp2p_swarm::behaviour::toggle::Toggle;
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
identify: identify::Behaviour,
ping: Toggle<ping::Behaviour>,
@ -287,8 +298,9 @@ fn with_either() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
kad: libp2p_kad::Kademlia<libp2p_kad::record::store::MemoryStore>,
ping_or_identify: Either<ping::Behaviour, identify::Behaviour>,
}
@ -304,12 +316,12 @@ fn custom_event_with_either() {
#[allow(clippy::large_enum_variant)]
enum BehaviourOutEvent {
Kad(libp2p::kad::KademliaEvent),
Kad(libp2p_kad::KademliaEvent),
PingOrIdentify(Either<ping::Event, identify::Event>),
}
impl From<libp2p::kad::KademliaEvent> for BehaviourOutEvent {
fn from(event: libp2p::kad::KademliaEvent) -> Self {
impl From<libp2p_kad::KademliaEvent> for BehaviourOutEvent {
fn from(event: libp2p_kad::KademliaEvent) -> Self {
BehaviourOutEvent::Kad(event)
}
}
@ -322,9 +334,12 @@ fn custom_event_with_either() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "BehaviourOutEvent")]
#[behaviour(
out_event = "BehaviourOutEvent",
prelude = "libp2p_swarm::derive_prelude"
)]
struct Foo {
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
kad: libp2p_kad::Kademlia<libp2p_kad::record::store::MemoryStore>,
ping_or_identify: Either<ping::Behaviour, identify::Behaviour>,
}
@ -338,6 +353,7 @@ fn custom_event_with_either() {
fn generated_out_event_derive_debug() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
#[behaviour(prelude = "libp2p_swarm::derive_prelude")]
struct Foo {
ping: ping::Behaviour,
}
@ -354,11 +370,11 @@ fn generated_out_event_derive_debug() {
#[test]
fn custom_out_event_no_type_parameters() {
use libp2p::core::connection::ConnectionId;
use libp2p::swarm::{
use libp2p_core::connection::ConnectionId;
use libp2p_core::PeerId;
use libp2p_swarm::{
ConnectionHandler, IntoConnectionHandler, NetworkBehaviourAction, PollParameters,
};
use libp2p::PeerId;
use std::task::Context;
use std::task::Poll;
@ -393,7 +409,7 @@ fn custom_out_event_no_type_parameters() {
}
#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent")]
#[behaviour(out_event = "OutEvent", prelude = "libp2p_swarm::derive_prelude")]
struct Behaviour<T: 'static + Send> {
custom: TemplatedBehaviour<T>,
}