diff --git a/CHANGELOG.md b/CHANGELOG.md index 28bc6874..e4393d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Cargo.toml b/Cargo.toml index e0086fe5..8b791f6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 } diff --git a/examples/chat-tokio.rs b/examples/chat-tokio.rs index 6bd77bd1..d4b0b121 100644 --- a/examples/chat-tokio.rs +++ b/examples/chat-tokio.rs @@ -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}; diff --git a/examples/chat.rs b/examples/chat.rs index cf1b84d1..26db660b 100644 --- a/examples/chat.rs +++ b/examples/chat.rs @@ -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; diff --git a/examples/distributed-key-value-store.rs b/examples/distributed-key-value-store.rs index 3323cc91..8d8c6d91 100644 --- a/examples/distributed-key-value-store.rs +++ b/examples/distributed-key-value-store.rs @@ -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; diff --git a/examples/file-sharing.rs b/examples/file-sharing.rs index d8600815..85c5d3d5 100644 --- a/examples/file-sharing.rs +++ b/examples/file-sharing.rs @@ -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; diff --git a/examples/gossipsub-chat.rs b/examples/gossipsub-chat.rs index e293b25b..e86d1836 100644 --- a/examples/gossipsub-chat.rs +++ b/examples/gossipsub-chat.rs @@ -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; diff --git a/examples/ipfs-private.rs b/examples/ipfs-private.rs index 1f6aec90..ddaa2889 100644 --- a/examples/ipfs-private.rs +++ b/examples/ipfs-private.rs @@ -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}; diff --git a/examples/ping.rs b/examples/ping.rs index 5d7443b8..a2da2834 100644 --- a/examples/ping.rs +++ b/examples/ping.rs @@ -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; diff --git a/misc/metrics/examples/metrics/main.rs b/misc/metrics/examples/metrics/main.rs index 0307e32d..1f661cb9 100644 --- a/misc/metrics/examples/metrics/main.rs +++ b/misc/metrics/examples/metrics/main.rs @@ -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; diff --git a/protocols/autonat/examples/autonat_client.rs b/protocols/autonat/examples/autonat_client.rs index c90a5c55..bdd54ff4 100644 --- a/protocols/autonat/examples/autonat_client.rs +++ b/protocols/autonat/examples/autonat_client.rs @@ -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; diff --git a/protocols/autonat/examples/autonat_server.rs b/protocols/autonat/examples/autonat_server.rs index 7bb79383..82a06b8b 100644 --- a/protocols/autonat/examples/autonat_server.rs +++ b/protocols/autonat/examples/autonat_server.rs @@ -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; diff --git a/protocols/dcutr/examples/dcutr.rs b/protocols/dcutr/examples/dcutr.rs index b239702d..bc33eddc 100644 --- a/protocols/dcutr/examples/dcutr.rs +++ b/protocols/dcutr/examples/dcutr.rs @@ -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; diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 64aca185..0bc5df7e 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -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] diff --git a/protocols/ping/tests/ping.rs b/protocols/ping/tests/ping.rs index 604d8317..0b21163b 100644 --- a/protocols/ping/tests/ping.rs +++ b/protocols/ping/tests/ping.rs @@ -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}; diff --git a/protocols/relay/examples/relay_v2.rs b/protocols/relay/examples/relay_v2.rs index 95027937..102637ca 100644 --- a/protocols/relay/examples/relay_v2.rs +++ b/protocols/relay/examples/relay_v2.rs @@ -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}; diff --git a/protocols/relay/tests/v2.rs b/protocols/relay/tests/v2.rs index e377a924..34e6e8ee 100644 --- a/protocols/relay/tests/v2.rs +++ b/protocols/relay/tests/v2.rs @@ -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] diff --git a/protocols/rendezvous/examples/discover.rs b/protocols/rendezvous/examples/discover.rs index c14e114e..0d1a6dac 100644 --- a/protocols/rendezvous/examples/discover.rs +++ b/protocols/rendezvous/examples/discover.rs @@ -143,7 +143,7 @@ impl From for MyEvent { } } -#[derive(libp2p::NetworkBehaviour)] +#[derive(libp2p::swarm::NetworkBehaviour)] #[behaviour(event_process = false)] #[behaviour(out_event = "MyEvent")] struct MyBehaviour { diff --git a/protocols/rendezvous/examples/register.rs b/protocols/rendezvous/examples/register.rs index 3fbfa027..471ff739 100644 --- a/protocols/rendezvous/examples/register.rs +++ b/protocols/rendezvous/examples/register.rs @@ -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; diff --git a/protocols/rendezvous/examples/register_with_identify.rs b/protocols/rendezvous/examples/register_with_identify.rs index f12a1a6e..bf30fa90 100644 --- a/protocols/rendezvous/examples/register_with_identify.rs +++ b/protocols/rendezvous/examples/register_with_identify.rs @@ -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; diff --git a/protocols/rendezvous/examples/rendezvous_point.rs b/protocols/rendezvous/examples/rendezvous_point.rs index 980a3a6f..c8688b98 100644 --- a/protocols/rendezvous/examples/rendezvous_point.rs +++ b/protocols/rendezvous/examples/rendezvous_point.rs @@ -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; diff --git a/protocols/rendezvous/tests/rendezvous.rs b/protocols/rendezvous/tests/rendezvous.rs index e9c4d871..85fdacd8 100644 --- a/protocols/rendezvous/tests/rendezvous.rs +++ b/protocols/rendezvous/tests/rendezvous.rs @@ -366,7 +366,7 @@ async fn new_impersonating_client() -> Swarm { eve } -#[derive(libp2p::NetworkBehaviour)] +#[derive(libp2p::swarm::NetworkBehaviour)] #[behaviour(event_process = false, out_event = "CombinedEvent")] struct CombinedBehaviour { client: rendezvous::client::Behaviour, diff --git a/src/lib.rs b/src/lib.rs index 2f8ac1ab..e2468547 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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: /// diff --git a/swarm-derive/CHANGELOG.md b/swarm-derive/CHANGELOG.md index 722537e6..fc5fb868 100644 --- a/swarm-derive/CHANGELOG.md +++ b/swarm-derive/CHANGELOG.md @@ -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 diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index 622e23f5..f21b86a9 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -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 "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" @@ -18,13 +18,7 @@ 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. +# 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] all-features = true diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index a2302857..fc8596e8 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -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::(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 = 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::(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> { - 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(ast: &DeriveInput, key: &str) -> Option +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> { if attr.path.segments.len() == 1 && attr.path.segments[0].ident == "behaviour" { match attr.parse_meta() { diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 67538ca9..f66828db 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -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]. diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 75dd0968..815013bc 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -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,13 +25,28 @@ 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" -# Passing arguments to the docsrs builder in order to properly document cfg's. +[[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 [package.metadata.docs.rs] all-features = true diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 385b7eaf..46f2d7c5 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -90,11 +90,12 @@ pub(crate) type THandlerOutEvent = /// 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; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6fbff5db..6927cfa0 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -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. diff --git a/swarm-derive/tests/test.rs b/swarm/tests/swarm_derive.rs similarity index 80% rename from swarm-derive/tests/test.rs rename to swarm/tests/swarm_derive.rs index 368fc7d3..a6c8a19d 100644 --- a/swarm-derive/tests/test.rs +++ b/swarm/tests/swarm_derive.rs @@ -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() {} +fn require_net_behaviour() {} // 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, + kad: libp2p_kad::Kademlia, } #[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 for MyEvent { - fn from(event: libp2p::identify::Event) -> Self { + impl From 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 for MyEvent { @@ -155,8 +158,8 @@ fn custom_event_mismatching_field_names() { } } - impl From for MyEvent { - fn from(event: libp2p::identify::Event) -> Self { + impl From 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 where ::OutEvent: Debug, @@ -184,6 +188,7 @@ fn bound() { fn where_clause() { #[allow(dead_code)] #[derive(NetworkBehaviour)] + #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Foo 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 for BehaviourOutEvent { - fn from(event: libp2p::identify::Event) -> Self { + impl From 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::(); - let mut _swarm: libp2p::Swarm = unimplemented!(); + let mut _swarm: libp2p_swarm::Swarm = 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, @@ -287,8 +298,9 @@ fn with_either() { #[allow(dead_code)] #[derive(NetworkBehaviour)] + #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Foo { - kad: libp2p::kad::Kademlia, + kad: libp2p_kad::Kademlia, ping_or_identify: Either, } @@ -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), } - impl From for BehaviourOutEvent { - fn from(event: libp2p::kad::KademliaEvent) -> Self { + impl From 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, + kad: libp2p_kad::Kademlia, ping_or_identify: Either, } @@ -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 { custom: TemplatedBehaviour, }