Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

swarm-derive/: Remove support for ignoring fields on struct #2842

Merged
merged 3 commits into from
Aug 29, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@

# `libp2p` facade crate

# 0.48.0 [unreleased]

- Update to `libp2p-swarm-derive` [`v0.30.0`](swarm-derive/CHANGELOG.md#0300).

# 0.47.0

- Update to [`libp2p-dcutr` `v0.5.0`](protocols/dcutr/CHANGELOG.md#050).
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "libp2p"
edition = "2021"
rust-version = "1.60.0"
description = "Peer-to-peer networking library"
version = "0.47.0"
version = "0.48.0"
authors = ["Parity Technologies <[email protected]>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand Down Expand Up @@ -93,7 +93,7 @@ libp2p-relay = { version = "0.11.0", path = "protocols/relay", optional = true }
libp2p-rendezvous = { version = "0.8.0", path = "protocols/rendezvous", optional = true }
libp2p-request-response = { version = "0.20.0", path = "protocols/request-response", optional = true }
libp2p-swarm = { version = "0.38.0", path = "swarm" }
libp2p-swarm-derive = { version = "0.29.0", path = "swarm-derive" }
libp2p-swarm-derive = { version = "0.30.0", path = "swarm-derive" }
libp2p-uds = { version = "0.34.0", path = "transports/uds", optional = true }
libp2p-wasm-ext = { version = "0.35.0", path = "transports/wasm-ext", default-features = false, optional = true }
libp2p-yamux = { version = "0.39.0", path = "muxers/yamux", optional = true }
Expand Down
5 changes: 0 additions & 5 deletions examples/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
struct MyBehaviour {
floodsub: Floodsub,
mdns: Mdns,

// Struct fields which do not implement NetworkBehaviour need to be ignored
#[behaviour(ignore)]
#[allow(dead_code)]
ignored_member: bool,
}

#[allow(clippy::large_enum_variant)]
Expand Down
4 changes: 4 additions & 0 deletions swarm-derive/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.30.0 - [unreleased]

- Remove support for non-`NetworkBehaviour` fields on main `struct` via `#[behaviour(ignore)]`.

# 0.29.0

- Generate `NetworkBehaviour::OutEvent` if not provided through `#[behaviour(out_event =
Expand Down
2 changes: 1 addition & 1 deletion swarm-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "libp2p-swarm-derive"
edition = "2021"
rust-version = "1.56.1"
description = "Procedural macros of libp2p-core"
version = "0.29.0"
version = "0.30.0"
authors = ["Parity Technologies <[email protected]>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand Down
84 changes: 37 additions & 47 deletions swarm-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
event_process
};

// The fields of the struct we are interested in (no ignored fields).
let data_struct_fields = data_struct
.fields
.iter()
.filter(|f| !is_ignored(f))
.collect::<Vec<_>>();

let (out_event_name, out_event_definition, out_event_from_clauses) = {
// If we find a `#[behaviour(out_event = "Foo")]` attribute on the
// struct, we set `Foo` as the out event. If not, the `OutEvent` is
Expand All @@ -125,7 +118,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// User provided `OutEvent`.
(Some(name), false) => {
let definition = None;
let from_clauses = data_struct_fields
let from_clauses = data_struct
.fields
.iter()
.map(|field| {
let ty = &field.ty;
Expand All @@ -138,7 +132,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
(None, false) => {
let name: syn::Type = syn::parse_str(&(ast.ident.to_string() + "Event")).unwrap();
let definition = {
let fields = data_struct_fields
let fields = data_struct
.fields
.iter()
.map(|field| {
let variant: syn::Variant = syn::parse_str(
Expand Down Expand Up @@ -173,7 +168,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// User uses `NetworkBehaviourEventProcess`.
(name, true) => {
let definition = None;
let from_clauses = data_struct_fields
let from_clauses = data_struct
.fields
.iter()
.map(|field| {
let ty = &field.ty;
Expand All @@ -191,7 +187,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the `where ...` clause of the trait implementation.
let where_clause = {
let additional = data_struct_fields
let additional = data_struct
.fields
.iter()
.map(|field| {
let ty = &field.ty;
Expand All @@ -213,7 +210,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `addresses_of_peer()`.
let addresses_of_peer_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -224,7 +222,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_connection_established()`.
let inject_connection_established_stmts = {
data_struct_fields.iter().enumerate().map(move |(field_n, field)| {
data_struct.fields.iter().enumerate().map(move |(field_n, field)| {
match field.ident {
Some(ref i) => quote!{ self.#i.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); },
None => quote!{ self.#field_n.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); },
Expand All @@ -234,7 +232,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_address_change()`.
let inject_address_change_stmts = {
data_struct_fields.iter().enumerate().map(move |(field_n, field)| {
data_struct.fields.iter().enumerate().map(move |(field_n, field)| {
match field.ident {
Some(ref i) => quote!{ self.#i.inject_address_change(peer_id, connection_id, old, new); },
None => quote!{ self.#field_n.inject_address_change(peer_id, connection_id, old, new); },
Expand All @@ -244,7 +242,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_connection_closed()`.
let inject_connection_closed_stmts = {
data_struct_fields
data_struct.fields
.iter()
.enumerate()
// The outmost handler belongs to the last behaviour.
Expand Down Expand Up @@ -273,7 +271,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_dial_failure()`.
let inject_dial_failure_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
// The outmost handler belongs to the last behaviour.
Expand Down Expand Up @@ -307,7 +306,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_listen_failure()`.
let inject_listen_failure_stmts = {
data_struct_fields
data_struct.fields
.iter()
.enumerate()
.rev()
Expand Down Expand Up @@ -335,7 +334,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_new_listener()`.
let inject_new_listener_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -346,7 +346,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_new_listen_addr()`.
let inject_new_listen_addr_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -357,7 +358,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_expired_listen_addr()`.
let inject_expired_listen_addr_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -368,7 +370,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_new_external_addr()`.
let inject_new_external_addr_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -379,7 +382,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_expired_external_addr()`.
let inject_expired_external_addr_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -390,7 +394,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_listener_error()`.
let inject_listener_error_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -401,7 +406,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {

// Build the list of statements to put in the body of `inject_listener_closed()`.
let inject_listener_closed_stmts = {
data_struct_fields
data_struct
.fields
.iter()
.enumerate()
.map(move |(field_n, field)| match field.ident {
Expand All @@ -414,14 +420,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
//
// The event type is a construction of nested `#either_ident`s of the events of the children.
// We call `inject_event` on the corresponding child.
let inject_node_event_stmts = data_struct_fields.iter().enumerate().enumerate().map(|(enum_n, (field_n, field))| {
let inject_node_event_stmts = data_struct.fields.iter().enumerate().enumerate().map(|(enum_n, (field_n, field))| {
let mut elem = if enum_n != 0 {
quote!{ #either_ident::Second(ev) }
} else {
quote!{ ev }
};

for _ in 0 .. data_struct_fields.len() - 1 - enum_n {
for _ in 0 .. data_struct.fields.len() - 1 - enum_n {
elem = quote!{ #either_ident::First(#elem) };
}

Expand All @@ -434,7 +440,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// The [`ConnectionHandler`] associated type.
let connection_handler_ty = {
let mut ph_ty = None;
for field in data_struct_fields.iter() {
for field in data_struct.fields.iter() {
let ty = &field.ty;
let field_info = quote! { <#ty as #trait_to_impl>::ConnectionHandler };
match ph_ty {
Expand All @@ -451,7 +457,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let new_handler = {
let mut out_handler = None;

for (field_n, field) in data_struct_fields.iter().enumerate() {
for (field_n, field) in data_struct.fields.iter().enumerate() {
let field_name = match field.ident {
Some(ref i) => quote! { self.#i },
None => quote! { self.#field_n },
Expand Down Expand Up @@ -498,7 +504,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// List of statements to put in `poll()`.
//
// We poll each child one by one and wrap around the output.
let poll_stmts = data_struct_fields.iter().enumerate().map(|(field_n, field)| {
let poll_stmts = data_struct.fields.iter().enumerate().map(|(field_n, field)| {
let field = field
.ident
.clone()
Expand All @@ -509,7 +515,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
} else {
quote!{ event }
};
for _ in 0 .. data_struct_fields.len() - 1 - field_n {
for _ in 0 .. data_struct.fields.len() - 1 - field_n {
wrapped_event = quote!{ #either_ident::First(#wrapped_event) };
}

Expand All @@ -520,7 +526,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let provided_handler_and_new_handlers = {
let mut out_handler = None;

for (f_n, f) in data_struct_fields.iter().enumerate() {
for (f_n, f) in data_struct.fields.iter().enumerate() {
let f_name = match f.ident {
Some(ref i) => quote! { self.#i },
None => quote! { self.#f_n },
Expand Down Expand Up @@ -706,19 +712,3 @@ fn get_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMeta>> {
None
}
}

/// Returns true if a field is marked as ignored by the user.
fn is_ignored(field: &syn::Field) -> bool {
for meta_items in field.attrs.iter().filter_map(get_meta_items) {
for meta_item in meta_items {
match meta_item {
syn::NestedMeta::Meta(syn::Meta::Path(ref m)) if m.is_ident("ignore") => {
return true;
}
_ => (),
}
}
}

false
}
48 changes: 0 additions & 48 deletions swarm-derive/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ fn three_fields() {
ping: libp2p::ping::Ping,
identify: libp2p::identify::Identify,
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
#[behaviour(ignore)]
foo: String,
}

#[allow(dead_code)]
Expand All @@ -103,30 +101,6 @@ fn three_fields() {
}
}

#[test]
fn three_fields_non_last_ignored() {
#[allow(dead_code)]
#[derive(NetworkBehaviour)]
struct Foo {
ping: libp2p::ping::Ping,
#[behaviour(ignore)]
identify: String,
kad: libp2p::kad::Kademlia<libp2p::kad::record::store::MemoryStore>,
}

#[allow(dead_code)]
#[allow(unreachable_code)]
fn foo() {
let _out_event: <Foo as NetworkBehaviour>::OutEvent = unimplemented!();
match _out_event {
FooEvent::Ping(libp2p::ping::Event { .. }) => {}
FooEvent::Kad(event) => {
let _: libp2p::kad::KademliaEvent = event;
}
}
}
}

#[test]
fn custom_polling() {
#[allow(dead_code)]
Expand Down Expand Up @@ -438,28 +412,6 @@ fn custom_event_with_either() {
}
}

#[test]
fn mixed_field_order() {
struct Foo {}

#[derive(NetworkBehaviour)]
pub struct Behaviour {
#[behaviour(ignore)]
_foo: Foo,
_ping: libp2p::ping::Ping,
#[behaviour(ignore)]
_foo2: Foo,
_identify: libp2p::identify::Identify,
#[behaviour(ignore)]
_foo3: Foo,
}

#[allow(dead_code)]
fn behaviour() {
require_net_behaviour::<Behaviour>();
}
}

#[test]
fn event_process() {
#[allow(dead_code)]
Expand Down
Loading