Skip to content

Commit

Permalink
swarm-derive/: Allow for templated behaviours (#2907)
Browse files Browse the repository at this point in the history
This patch fixes an issue where we couldn't use type parameters on a behaviour
with a custom out event that had different type parameters.
  • Loading branch information
thomaseizinger committed Sep 16, 2022
1 parent c81b06a commit 2025de3
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -47,6 +47,8 @@

- Update to [`libp2p-tcp` `v0.37.0`](transports/tcp/CHANGELOG.md#0370).

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

- Update to [`libp2p-metrics` `v0.10.0`](misc/metrics/CHANGELOG.md#0100).

- Update to [`libp2p-kad` `v0.41.0`](protocols/kad/CHANGELOG.md#0410).
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -96,7 +96,7 @@ libp2p-relay = { version = "0.12.0", path = "protocols/relay", optional = true }
libp2p-rendezvous = { version = "0.9.0", path = "protocols/rendezvous", optional = true }
libp2p-request-response = { version = "0.21.0", path = "protocols/request-response", optional = true }
libp2p-swarm = { version = "0.39.0", path = "swarm" }
libp2p-swarm-derive = { version = "0.30.0", path = "swarm-derive" }
libp2p-swarm-derive = { version = "0.30.1", path = "swarm-derive" }
libp2p-uds = { version = "0.35.0", path = "transports/uds", optional = true }
libp2p-wasm-ext = { version = "0.36.0", path = "transports/wasm-ext", default-features = false, optional = true }
libp2p-yamux = { version = "0.40.0", path = "muxers/yamux", optional = true }
Expand Down
7 changes: 7 additions & 0 deletions swarm-derive/CHANGELOG.md
@@ -1,3 +1,10 @@
# 0.30.1 [unreleased]

- Fix an issue where the derive would generate bad code if the type parameters between the behaviour and a custom
out event differed. See [PR 2907].

[PR 2907]: https://github.com/libp2p/rust-libp2p/pull/2907

# 0.30.0

- Remove support for removed `NetworkBehaviourEventProcess`. See [PR 2840].
Expand Down
3 changes: 2 additions & 1 deletion swarm-derive/Cargo.toml
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.30.0"
version = "0.30.1"
authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand All @@ -22,3 +22,4 @@ syn = { version = "1.0.8", default-features = false, features = ["clone-impls",
libp2p = { path = "../", default-features = false, features = ["ping", "identify", "kad"] }
either = "1.6.0"
futures = "0.3.1"
void = "1"
10 changes: 8 additions & 2 deletions swarm-derive/src/lib.rs
Expand Up @@ -100,7 +100,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
.iter()
.map(|field| {
let ty = &field.ty;
quote! {#name #ty_generics: From< <#ty as #trait_to_impl>::OutEvent >}
quote! {#name: From< <#ty as #trait_to_impl>::OutEvent >}
})
.collect::<Vec<_>>();
(name, definition, from_clauses)
Expand Down Expand Up @@ -537,6 +537,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
})
});

let out_event_reference = if out_event_definition.is_some() {
quote! { #out_event_name #ty_generics }
} else {
quote! { #out_event_name }
};

// Now the magic happens.
let final_quote = quote! {
#out_event_definition
Expand All @@ -545,7 +551,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
#where_clause
{
type ConnectionHandler = #connection_handler_ty;
type OutEvent = #out_event_name #ty_generics;
type OutEvent = #out_event_reference;

fn new_handler(&mut self) -> Self::ConnectionHandler {
use #into_connection_handler;
Expand Down
62 changes: 62 additions & 0 deletions swarm-derive/tests/test.rs
Expand Up @@ -350,3 +350,65 @@ fn generated_out_event_derive_debug() {

require_debug::<Foo>();
}

#[test]
fn custom_out_event_no_type_parameters() {
use libp2p::core::connection::ConnectionId;
use libp2p::swarm::handler::DummyConnectionHandler;
use libp2p::swarm::{
ConnectionHandler, IntoConnectionHandler, NetworkBehaviourAction, PollParameters,
};
use libp2p::PeerId;
use std::task::Context;
use std::task::Poll;

pub struct TemplatedBehaviour<T: 'static> {
_data: T,
}

impl<T> NetworkBehaviour for TemplatedBehaviour<T> {
type ConnectionHandler = DummyConnectionHandler;
type OutEvent = void::Void;

fn new_handler(&mut self) -> Self::ConnectionHandler {
DummyConnectionHandler::default()
}

fn inject_event(
&mut self,
_peer: PeerId,
_connection: ConnectionId,
message: <<Self::ConnectionHandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent,
) {
void::unreachable(message);
}

fn poll(
&mut self,
_ctx: &mut Context,
_: &mut impl PollParameters,
) -> Poll<NetworkBehaviourAction<Self::OutEvent, Self::ConnectionHandler>> {
Poll::Pending
}
}

#[derive(NetworkBehaviour)]
#[behaviour(out_event = "OutEvent")]
struct Behaviour<T: 'static + Send> {
custom: TemplatedBehaviour<T>,
}

#[derive(Debug)]
enum OutEvent {
None,
}

impl From<void::Void> for OutEvent {
fn from(_e: void::Void) -> Self {
Self::None
}
}

require_net_behaviour::<Behaviour<String>>();
require_net_behaviour::<Behaviour<()>>();
}

0 comments on commit 2025de3

Please sign in to comment.