mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-17 12:01:23 +00:00
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:
@ -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
|
||||
|
||||
|
21
Cargo.toml
21
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 }
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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]
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
///
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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() {
|
||||
|
@ -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].
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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>,
|
||||
}
|
Reference in New Issue
Block a user