feat(swarm): rename associated types for message passing

Previously, the associated types on `NetworkBehaviour` and `ConnectionHandler` carried generic names like `InEvent` and `OutEvent`. These names are _correct_ in that `OutEvent`s are passed out and `InEvent`s are passed in but they don't help users understand how these types are used.

In theory, a `ConnectionHandler` could be used separately from `NetworkBehaviour`s but that is highly unlikely. Thus, we rename these associated types to indicate, where the message is going to be sent to:

- `NetworkBehaviour::OutEvent` is renamed to `ToSwarm`: It describes the message(s) a `NetworkBehaviour` can emit to the `Swarm`. The user is going to receive those in `SwarmEvent::Behaviour`.
- `ConnectionHandler::InEvent` is renamed to `FromBehaviour`: It describes the message(s) a `ConnectionHandler` can receive from its behaviour via `ConnectionHandler::on_swarm_event`. The `NetworkBehaviour` can send it via the `ToSwarm::NotifyHandler` command.
- `ConnectionHandler::OutEvent` is renamed to `ToBehaviour`: It describes the message(s) a `ConnectionHandler` can send back to the behaviour via the now also renamed `ConnectionHandlerEvent::NotifyBehaviour` (previously `ConnectionHandlerEvent::Custom`)

Resolves: #2854.

Pull-Request: #3848.
This commit is contained in:
Thomas Coratger
2023-05-14 12:58:08 +02:00
committed by GitHub
parent 5b32c8a0d2
commit 6e36e8aa35
65 changed files with 355 additions and 236 deletions

View File

@@ -54,6 +54,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let BehaviourAttributes {
prelude_path,
user_specified_out_event,
deprecation_tokenstream,
} = match parse_attributes(ast) {
Ok(attrs) => attrs,
Err(e) => return e,
@@ -96,11 +97,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
};
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
// If we find a `#[behaviour(to_swarm = "Foo")]` attribute on the
// struct, we set `Foo` as the out event. If not, the `ToSwarm` is
// generated.
match user_specified_out_event {
// User provided `OutEvent`.
// User provided `ToSwarm`.
Some(name) => {
let definition = None;
let from_clauses = data_struct
@@ -108,12 +109,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
.iter()
.map(|field| {
let ty = &field.ty;
quote! {#name: From< <#ty as #trait_to_impl>::OutEvent >}
quote! {#name: From< <#ty as #trait_to_impl>::ToSwarm >}
})
.collect::<Vec<_>>();
(name, definition, from_clauses)
}
// User did not provide `OutEvent`. Generate it.
// User did not provide `ToSwarm`. Generate it.
None => {
let enum_name_str = ast.ident.to_string() + "Event";
let enum_name: syn::Type =
@@ -135,7 +136,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let enum_variants = fields
.clone()
.map(|(variant, ty)| quote! {#variant(<#ty as #trait_to_impl>::OutEvent)});
.map(|(variant, ty)| quote! {#variant(<#ty as #trait_to_impl>::ToSwarm)});
let visibility = &ast.vis;
@@ -146,7 +147,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
let additional_debug = fields
.clone()
.map(|(_variant, ty)| quote! { <#ty as #trait_to_impl>::OutEvent : ::core::fmt::Debug })
.map(|(_variant, ty)| quote! { <#ty as #trait_to_impl>::ToSwarm : ::core::fmt::Debug })
.collect::<Vec<_>>();
let where_clause = {
@@ -168,7 +169,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
.map(|where_clause| quote! {#where_clause, #(#additional_debug),*});
let match_variants = fields.map(|(variant, _ty)| variant);
let msg = format!("`NetworkBehaviour::OutEvent` produced by {name}.");
let msg = format!("`NetworkBehaviour::ToSwarm` produced by {name}.");
Some(quote! {
#[doc = #msg]
@@ -677,9 +678,9 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
}
let generate_event_match_arm = {
// If the `NetworkBehaviour`'s `OutEvent` is generated by the derive macro, wrap the sub
// `NetworkBehaviour` `OutEvent` in the variant of the generated `OutEvent`. If the
// `NetworkBehaviour`'s `OutEvent` is provided by the user, use the corresponding `From`
// If the `NetworkBehaviour`'s `ToSwarm` is generated by the derive macro, wrap the sub
// `NetworkBehaviour` `ToSwarm` in the variant of the generated `ToSwarm`. If the
// `NetworkBehaviour`'s `ToSwarm` is provided by the user, use the corresponding `From`
// implementation.
let into_out_event = if out_event_definition.is_some() {
let event_variant: syn::Variant = syn::parse_str(
@@ -731,13 +732,15 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
// Now the magic happens.
let final_quote = quote! {
#deprecation_tokenstream
#out_event_definition
impl #impl_generics #trait_to_impl for #name #ty_generics
#where_clause
{
type ConnectionHandler = #connection_handler_ty;
type OutEvent = #out_event_reference;
type ToSwarm = #out_event_reference;
#[allow(clippy::needless_question_mark)]
fn handle_pending_inbound_connection(
@@ -795,7 +798,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, #t_handler_in_event<Self>>> {
fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action<Self::ToSwarm, #t_handler_in_event<Self>>> {
use #prelude_path::futures::*;
#(#poll_stmts)*
std::task::Poll::Pending
@@ -851,6 +854,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
struct BehaviourAttributes {
prelude_path: syn::Path,
user_specified_out_event: Option<syn::Type>,
deprecation_tokenstream: proc_macro2::TokenStream,
}
/// Parses the `value` of a key=value pair in the `#[behaviour]` attribute into the requested type.
@@ -858,7 +862,9 @@ fn parse_attributes(ast: &DeriveInput) -> Result<BehaviourAttributes, TokenStrea
let mut attributes = BehaviourAttributes {
prelude_path: syn::parse_quote! { ::libp2p::swarm::derive_prelude },
user_specified_out_event: None,
deprecation_tokenstream: proc_macro2::TokenStream::new(),
};
let mut is_out_event = false;
for attr in ast
.attrs
@@ -896,7 +902,10 @@ fn parse_attributes(ast: &DeriveInput) -> Result<BehaviourAttributes, TokenStrea
continue;
}
if meta.path().is_ident("out_event") {
if meta.path().is_ident("to_swarm") || meta.path().is_ident("out_event") {
if meta.path().is_ident("out_event") {
is_out_event = true;
}
match meta {
Meta::Path(_) => unimplemented!(),
Meta::List(_) => unimplemented!(),
@@ -914,7 +923,7 @@ fn parse_attributes(ast: &DeriveInput) -> Result<BehaviourAttributes, TokenStrea
Meta::NameValue(name_value) => {
return Err(syn::Error::new_spanned(
name_value.value,
"`out_event` value must be a quoted type",
"`to_swarm` value must be a quoted type",
)
.to_compile_error()
.into());
@@ -926,5 +935,15 @@ fn parse_attributes(ast: &DeriveInput) -> Result<BehaviourAttributes, TokenStrea
}
}
if is_out_event {
let warning = proc_macro_warning::Warning::new_deprecated("out_event_renamed_to_to_swarm")
.old("use the out_event attribute `#[behaviour(out_event = ...)]`")
.new("use the to_swarm attribute `#[behaviour(to_swarm = ...)]`")
.span(ast.ident.span())
.build();
attributes.deprecation_tokenstream = quote::quote! { #warning };
}
Ok(attributes)
}