mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 01:51:23 +00:00
Embed the topology in the NetworkBehaviour (#889)
* Embed the topology in the NetworkBehaviour * Put topologies inside of Floodsub and Kad * Fix core tests * Fix chat example * More work * Some cleanup * Restore external addresses system
This commit is contained in:
@ -49,6 +49,7 @@ 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::core::swarm::NetworkBehaviour};
|
||||
let net_behv_event_proc = quote!{::libp2p::core::swarm::NetworkBehaviourEventProcess};
|
||||
let either_ident = quote!{::libp2p::core::either::EitherOutput};
|
||||
@ -70,25 +71,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
quote!{#n}
|
||||
};
|
||||
|
||||
// Name of the type parameter that represents the topology.
|
||||
let topology_generic = {
|
||||
let mut n = "TTopology".to_string();
|
||||
// Avoid collisions.
|
||||
while ast.generics.type_params().any(|tp| tp.ident.to_string() == n) {
|
||||
n.push('1');
|
||||
}
|
||||
let n = Ident::new(&n, name.span());
|
||||
quote!{#n}
|
||||
};
|
||||
|
||||
let poll_parameters = quote!{::libp2p::core::swarm::PollParameters<#topology_generic>};
|
||||
let poll_parameters = quote!{::libp2p::core::swarm::PollParameters};
|
||||
|
||||
// Build the generics.
|
||||
let impl_generics = {
|
||||
let tp = ast.generics.type_params();
|
||||
let lf = ast.generics.lifetimes();
|
||||
let cst = ast.generics.const_params();
|
||||
quote!{<#(#lf,)* #(#tp,)* #(#cst,)* #topology_generic, #substream_generic>}
|
||||
quote!{<#(#lf,)* #(#tp,)* #(#cst,)* #substream_generic>}
|
||||
};
|
||||
|
||||
// Build the `where ...` clause of the trait implementation.
|
||||
@ -98,12 +88,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
.flat_map(|field| {
|
||||
let ty = &field.ty;
|
||||
vec![
|
||||
quote!{#ty: #trait_to_impl<#topology_generic>},
|
||||
quote!{Self: #net_behv_event_proc<<#ty as #trait_to_impl<#topology_generic>>::OutEvent>},
|
||||
quote!{<<#ty as #trait_to_impl<#topology_generic>>::ProtocolsHandler as #into_protocols_handler>::Handler: #protocols_handler<Substream = #substream_generic>},
|
||||
quote!{#ty: #trait_to_impl},
|
||||
quote!{Self: #net_behv_event_proc<<#ty as #trait_to_impl>::OutEvent>},
|
||||
quote!{<<#ty as #trait_to_impl>::ProtocolsHandler as #into_protocols_handler>::Handler: #protocols_handler<Substream = #substream_generic>},
|
||||
// Note: this bound is required because of https://github.com/rust-lang/rust/issues/55697
|
||||
quote!{<<<#ty as #trait_to_impl<#topology_generic>>::ProtocolsHandler as #into_protocols_handler>::Handler as #protocols_handler>::InboundProtocol: ::libp2p::core::InboundUpgrade<#substream_generic>},
|
||||
quote!{<<<#ty as #trait_to_impl<#topology_generic>>::ProtocolsHandler as #into_protocols_handler>::Handler as #protocols_handler>::OutboundProtocol: ::libp2p::core::OutboundUpgrade<#substream_generic>},
|
||||
quote!{<<<#ty as #trait_to_impl>::ProtocolsHandler as #into_protocols_handler>::Handler as #protocols_handler>::InboundProtocol: ::libp2p::core::InboundUpgrade<#substream_generic>},
|
||||
quote!{<<<#ty as #trait_to_impl>::ProtocolsHandler as #into_protocols_handler>::Handler as #protocols_handler>::OutboundProtocol: ::libp2p::core::OutboundUpgrade<#substream_generic>},
|
||||
]
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@ -143,6 +133,20 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
out
|
||||
};
|
||||
|
||||
// Build the list of statements to put in the body of `addresses_of_peer()`.
|
||||
let addresses_of_peer_stmts = {
|
||||
data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| {
|
||||
if is_ignored(&field) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(match field.ident {
|
||||
Some(ref i) => quote!{ out.extend(self.#i.addresses_of_peer(peer_id)); },
|
||||
None => quote!{ out.extend(self.#field_n.addresses_of_peer(peer_id)); },
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// Build the list of statements to put in the body of `inject_connected()`.
|
||||
let inject_connected_stmts = {
|
||||
let num_fields = data_struct.fields.iter().filter(|f| !is_ignored(f)).count();
|
||||
@ -216,7 +220,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
continue;
|
||||
}
|
||||
let ty = &field.ty;
|
||||
let field_info = quote!{ <#ty as #trait_to_impl<#topology_generic>>::ProtocolsHandler };
|
||||
let field_info = quote!{ <#ty as #trait_to_impl>::ProtocolsHandler };
|
||||
match ph_ty {
|
||||
Some(ev) => ph_ty = Some(quote!{ #into_proto_select_ident<#ev, #field_info> }),
|
||||
ref mut ev @ None => *ev = Some(field_info),
|
||||
@ -321,7 +325,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
|
||||
// Now the magic happens.
|
||||
let final_quote = quote!{
|
||||
impl #impl_generics #trait_to_impl<#topology_generic> for #name #ty_generics
|
||||
impl #impl_generics #trait_to_impl for #name #ty_generics
|
||||
#where_clause
|
||||
{
|
||||
type ProtocolsHandler = #protocols_handler_ty;
|
||||
@ -333,6 +337,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream {
|
||||
#new_handler
|
||||
}
|
||||
|
||||
fn addresses_of_peer(&self, peer_id: &#peer_id) -> Vec<#multiaddr> {
|
||||
let mut out = Vec::new();
|
||||
#(#addresses_of_peer_stmts);*
|
||||
out
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inject_connected(&mut self, peer_id: #peer_id, endpoint: #connected_point) {
|
||||
#(#inject_connected_stmts);*
|
||||
|
Reference in New Issue
Block a user