mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 18:07:58 +00:00
feat: add proc macro to reduce overseer mock boilerplate (#2949)
This commit is contained in:
committed by
GitHub
parent
f36d8efb3d
commit
1ef8eac8ec
Generated
+12
@@ -6179,6 +6179,7 @@ dependencies = [
|
||||
"polkadot-node-subsystem",
|
||||
"polkadot-node-subsystem-util",
|
||||
"polkadot-primitives",
|
||||
"polkadot-procmacro-overseer-subsystems-gen",
|
||||
"sc-client-api",
|
||||
"sp-api",
|
||||
"sp-core",
|
||||
@@ -6229,6 +6230,17 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkadot-procmacro-overseer-subsystems-gen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"trybuild",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkadot-procmacro-subsystem-dispatch-gen"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -12,6 +12,7 @@ futures = "0.3.12"
|
||||
futures-timer = "3.0.2"
|
||||
polkadot-node-primitives = { package = "polkadot-node-primitives", path = "../primitives" }
|
||||
polkadot-node-subsystem-util = { path = "../subsystem-util" }
|
||||
polkadot-procmacro-overseer-subsystems-gen = { path = "./subsystems-gen" }
|
||||
polkadot-primitives = { path = "../../primitives" }
|
||||
polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../subsystem" }
|
||||
tracing = "0.1.25"
|
||||
|
||||
@@ -94,6 +94,7 @@ pub use polkadot_subsystem::{
|
||||
};
|
||||
use polkadot_node_subsystem_util::{TimeoutExt, metrics::{self, prometheus}, metered, Metronome};
|
||||
use polkadot_node_primitives::SpawnNamed;
|
||||
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
|
||||
|
||||
// A capacity of bounded channels inside the overseer.
|
||||
const CHANNEL_CAPACITY: usize = 1024;
|
||||
@@ -143,7 +144,7 @@ impl<Client> HeadSupportsParachains for Arc<Client> where
|
||||
/// Each [`Subsystem`] is supposed to implement some interface that is generic over
|
||||
/// message type that is specific to this [`Subsystem`]. At the moment not all
|
||||
/// subsystems are implemented and the rest can be mocked with the [`DummySubsystem`].
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, AllSubsystemsGen)]
|
||||
pub struct AllSubsystems<
|
||||
CV = (), CB = (), CS = (), SD = (), AD = (), AR = (), BS = (), BD = (), P = (),
|
||||
RA = (), AS = (), NB = (), CA = (), CG = (), CP = (), ApD = (), ApV = (),
|
||||
@@ -244,492 +245,6 @@ impl<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS>
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `candidate_validation` instance in `self`.
|
||||
pub fn replace_candidate_validation<NEW>(
|
||||
self,
|
||||
candidate_validation: NEW,
|
||||
) -> AllSubsystems<NEW, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `candidate_backing` instance in `self`.
|
||||
pub fn replace_candidate_backing<NEW>(
|
||||
self,
|
||||
candidate_backing: NEW,
|
||||
) -> AllSubsystems<CV, NEW, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `candidate_selection` instance in `self`.
|
||||
pub fn replace_candidate_selection<NEW>(
|
||||
self,
|
||||
candidate_selection: NEW,
|
||||
) -> AllSubsystems<CV, CB, NEW, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `statement_distribution` instance in `self`.
|
||||
pub fn replace_statement_distribution<NEW>(
|
||||
self,
|
||||
statement_distribution: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, NEW, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `availability_distribution` instance in `self`.
|
||||
pub fn replace_availability_distribution<NEW>(
|
||||
self,
|
||||
availability_distribution: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, NEW, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `availability_recovery` instance in `self`.
|
||||
pub fn replace_availability_recovery<NEW>(
|
||||
self,
|
||||
availability_recovery: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, NEW, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `bitfield_signing` instance in `self`.
|
||||
pub fn replace_bitfield_signing<NEW>(
|
||||
self,
|
||||
bitfield_signing: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, NEW, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `bitfield_distribution` instance in `self`.
|
||||
pub fn replace_bitfield_distribution<NEW>(
|
||||
self,
|
||||
bitfield_distribution: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, NEW, P, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `provisioner` instance in `self`.
|
||||
pub fn replace_provisioner<NEW>(
|
||||
self,
|
||||
provisioner: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, NEW, RA, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `runtime_api` instance in `self`.
|
||||
pub fn replace_runtime_api<NEW>(
|
||||
self,
|
||||
runtime_api: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, NEW, AS, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `availability_store` instance in `self`.
|
||||
pub fn replace_availability_store<NEW>(
|
||||
self,
|
||||
availability_store: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, NEW, NB, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `network_bridge` instance in `self`.
|
||||
pub fn replace_network_bridge<NEW>(
|
||||
self,
|
||||
network_bridge: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NEW, CA, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `chain_api` instance in `self`.
|
||||
pub fn replace_chain_api<NEW>(
|
||||
self,
|
||||
chain_api: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, NEW, CG, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `collation_generation` instance in `self`.
|
||||
pub fn replace_collation_generation<NEW>(
|
||||
self,
|
||||
collation_generation: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, NEW, CP, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `collator_protocol` instance in `self`.
|
||||
pub fn replace_collator_protocol<NEW>(
|
||||
self,
|
||||
collator_protocol: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, NEW, ApD, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `approval_distribution` instance in `self`.
|
||||
pub fn replace_approval_distribution<NEW>(
|
||||
self,
|
||||
approval_distribution: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, NEW, ApV, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `approval_voting` instance in `self`.
|
||||
pub fn replace_approval_voting<NEW>(
|
||||
self,
|
||||
approval_voting: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, NEW, GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting,
|
||||
gossip_support: self.gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace the `gossip_support` instance in `self`.
|
||||
pub fn replace_gossip_support<NEW>(
|
||||
self,
|
||||
gossip_support: NEW,
|
||||
) -> AllSubsystems<CV, CB, CS, SD, AD, AR, BS, BD, P, RA, AS, NB, CA, CG, CP, ApD, ApV, NEW> {
|
||||
AllSubsystems {
|
||||
candidate_validation: self.candidate_validation,
|
||||
candidate_backing: self.candidate_backing,
|
||||
candidate_selection: self.candidate_selection,
|
||||
statement_distribution: self.statement_distribution,
|
||||
availability_distribution: self.availability_distribution,
|
||||
availability_recovery: self.availability_recovery,
|
||||
bitfield_signing: self.bitfield_signing,
|
||||
bitfield_distribution: self.bitfield_distribution,
|
||||
provisioner: self.provisioner,
|
||||
runtime_api: self.runtime_api,
|
||||
availability_store: self.availability_store,
|
||||
network_bridge: self.network_bridge,
|
||||
chain_api: self.chain_api,
|
||||
collation_generation: self.collation_generation,
|
||||
collator_protocol: self.collator_protocol,
|
||||
approval_distribution: self.approval_distribution,
|
||||
approval_voting: self.approval_voting,
|
||||
gossip_support,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_ref(&self) -> AllSubsystems<&'_ CV, &'_ CB, &'_ CS, &'_ SD, &'_ AD, &'_ AR, &'_ BS, &'_ BD, &'_ P, &'_ RA, &'_ AS, &'_ NB, &'_ CA, &'_ CG, &'_ CP, &'_ ApD, &'_ ApV, &'_ GS> {
|
||||
AllSubsystems {
|
||||
candidate_validation: &self.candidate_validation,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "polkadot-procmacro-overseer-subsystems-gen"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
description = "Small proc macro to create mocking level iface type helpers"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1.0.60", features = ["full", "extra-traits"] }
|
||||
quote = "1.0.9"
|
||||
proc-macro2 = "1.0.24"
|
||||
assert_matches = "1.5.0"
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0.41"
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright 2021 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
use syn::{Error, GenericParam, Ident, Result, Type, parse2};
|
||||
|
||||
#[proc_macro_derive(AllSubsystemsGen)]
|
||||
pub fn subsystems_gen(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let item: TokenStream = item.into();
|
||||
impl_subsystems_gen(item).unwrap_or_else(|err| err.to_compile_error()).into()
|
||||
}
|
||||
|
||||
fn impl_subsystems_gen(item: TokenStream) -> Result<proc_macro2::TokenStream> {
|
||||
let span = proc_macro2::Span::call_site();
|
||||
let ds = parse2::<syn::ItemStruct>(item.clone())?;
|
||||
|
||||
match ds.fields {
|
||||
syn::Fields::Named(named) => {
|
||||
#[derive(Clone)]
|
||||
struct NameTyTup {
|
||||
field: Ident,
|
||||
ty: Type,
|
||||
}
|
||||
let mut orig_generics = ds.generics;
|
||||
// remove default types
|
||||
orig_generics.params = orig_generics.params.into_iter().map(|mut generic| {
|
||||
match generic {
|
||||
GenericParam::Type(ref mut param) => {
|
||||
param.eq_token = None;
|
||||
param.default = None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
generic
|
||||
}).collect();
|
||||
|
||||
// prepare a hashmap of generic type to member that uses it
|
||||
let generic_types = orig_generics.params.iter().filter_map(|generic| {
|
||||
if let GenericParam::Type(param) = generic {
|
||||
Some(param.ident.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect::<HashSet<Ident>>();
|
||||
|
||||
let strukt_ty = ds.ident;
|
||||
|
||||
if generic_types.is_empty() {
|
||||
return Err(Error::new(strukt_ty.span(), "struct must have at least one generic parameter."))
|
||||
}
|
||||
|
||||
// collect all fields that exist, and all fields that are replaceable
|
||||
let mut replacable_items = Vec::<NameTyTup>::with_capacity(64);
|
||||
let mut all_fields = replacable_items.clone();
|
||||
|
||||
|
||||
let mut duplicate_generic_detection = HashSet::<Ident>::with_capacity(64);
|
||||
|
||||
for field in named.named {
|
||||
let field_ident = field.ident.clone().ok_or_else(|| Error::new(span, "Member field must have a name."))?;
|
||||
let ty = field.ty.clone();
|
||||
let ntt = NameTyTup { field: field_ident, ty };
|
||||
|
||||
replacable_items.push(ntt.clone());
|
||||
|
||||
|
||||
// assure every generic is used exactly once
|
||||
let ty_ident = match field.ty {
|
||||
Type::Path(path) => path.path.get_ident().cloned().ok_or_else(|| {
|
||||
Error::new(proc_macro2::Span::call_site(), "Expected an identifier, but got a path.")
|
||||
}),
|
||||
_ => return Err(Error::new(proc_macro2::Span::call_site(), "Must be path."))
|
||||
}?;
|
||||
|
||||
if generic_types.contains(&ty_ident) {
|
||||
if let Some(previous) = duplicate_generic_detection.replace(ty_ident) {
|
||||
return Err(Error::new(previous.span(), "Generic type parameters may only be used for exactly one field, but is used more than once."))
|
||||
}
|
||||
}
|
||||
|
||||
all_fields.push(ntt);
|
||||
}
|
||||
|
||||
|
||||
let msg = "Generated by #[derive(AllSubsystemsGen)] derive proc-macro.";
|
||||
let mut additive = TokenStream::new();
|
||||
|
||||
// generate an impl of `fn replace_#name`
|
||||
for NameTyTup { field: replacable_item, ty: replacable_item_ty } in replacable_items {
|
||||
let keeper = all_fields.iter().filter(|ntt| ntt.field != replacable_item).map(|ntt| ntt.field.clone());
|
||||
let strukt_ty = strukt_ty.clone();
|
||||
let fname = Ident::new(&format!("replace_{}", replacable_item), span);
|
||||
// adjust the generics such that the appropriate member type is replaced
|
||||
let mut modified_generics = orig_generics.clone();
|
||||
modified_generics.params = modified_generics.params.into_iter().map(|mut generic| {
|
||||
match generic {
|
||||
GenericParam::Type(ref mut param) => {
|
||||
param.eq_token = None;
|
||||
param.default = None;
|
||||
if match &replacable_item_ty {
|
||||
Type::Path(path) =>
|
||||
path.path.get_ident().filter(|&ident| ident == ¶m.ident).is_some(),
|
||||
_ => false
|
||||
} {
|
||||
param.ident = Ident::new("NEW", span);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
generic
|
||||
}).collect();
|
||||
|
||||
additive.extend(quote! {
|
||||
impl #orig_generics #strukt_ty #orig_generics {
|
||||
#[doc = #msg]
|
||||
pub fn #fname < NEW > (self, replacement: NEW) -> #strukt_ty #modified_generics {
|
||||
#strukt_ty :: #modified_generics {
|
||||
#replacable_item: replacement,
|
||||
#(
|
||||
#keeper: self.#keeper,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(additive)
|
||||
}
|
||||
syn::Fields::Unit => Err(Error::new(span, "Must be a struct with named fields. Not an unit struct.")),
|
||||
syn::Fields::Unnamed(_) => {
|
||||
Err(Error::new(span, "Must be a struct with named fields. Not an unnamed fields struct."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn basic() {
|
||||
let item = quote! {
|
||||
pub struct AllSubsystems<A,B,CD> {
|
||||
pub a: A,
|
||||
pub beee: B,
|
||||
pub dj: CD,
|
||||
}
|
||||
};
|
||||
|
||||
let output = impl_subsystems_gen(item).expect("Simple example always works. qed");
|
||||
println!("//generated:");
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/err-*.rs");
|
||||
t.pass("tests/ui/ok-*.rs");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
|
||||
|
||||
#[derive(Clone, AllSubsystemsGen)]
|
||||
enum AllSubsystems<A,B> {
|
||||
A(A),
|
||||
B(B),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let all = AllSubsystems::<u8,u16>::A(0u8);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
error: expected `struct`
|
||||
--> $DIR/err-01-enum.rs:6:1
|
||||
|
|
||||
6 | enum AllSubsystems<A,B> {
|
||||
| ^^^^
|
||||
@@ -0,0 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
|
||||
|
||||
#[derive(Clone, AllSubsystemsGen)]
|
||||
struct AllSubsystems<X> {
|
||||
a: X,
|
||||
b: X,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let all = AllSubsystems::<u16> {
|
||||
a: 0_u16,
|
||||
b: 1_u16,
|
||||
};
|
||||
let _all = all.replace_a(77u8);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
error: Generic type parameters may only be used for exactly one field, but is used more than once.
|
||||
--> $DIR/err-01-generic-used-twice.rs:7:5
|
||||
|
|
||||
7 | a: X,
|
||||
| ^
|
||||
|
||||
error[E0599]: no method named `replace_a` found for struct `AllSubsystems<u16>` in the current scope
|
||||
--> $DIR/err-01-generic-used-twice.rs:16:17
|
||||
|
|
||||
6 | struct AllSubsystems<X> {
|
||||
| ----------------------- method `replace_a` not found for this
|
||||
...
|
||||
16 | let _all = all.replace_a(77u8);
|
||||
| ^^^^^^^^^ method not found in `AllSubsystems<u16>`
|
||||
@@ -0,0 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
|
||||
|
||||
#[derive(Clone, AllSubsystemsGen)]
|
||||
struct AllSubsystems {
|
||||
a: f32,
|
||||
b: u16,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let all = AllSubsystems {
|
||||
a: 0_f32,
|
||||
b: 1_u16,
|
||||
};
|
||||
let _all = all.replace_a(77u8);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
error: Generic type parameters may only be used once have at least one generic parameter.
|
||||
--> $DIR/err-01-no-generics.rs:7:5
|
||||
|
|
||||
7 | a: X,
|
||||
| ^
|
||||
|
||||
error[E0599]: no method named `replace_a` found for struct `AllSubsystems<u16>` in the current scope
|
||||
--> $DIR/err-01-no-generics.rs:16:17
|
||||
|
|
||||
6 | struct AllSubsystems<X> {
|
||||
| ----------------------- method `replace_a` not found for this
|
||||
...
|
||||
16 | let _all = all.replace_a(77u8);
|
||||
| ^^^^^^^^^ method not found in `AllSubsystems<u16>`
|
||||
@@ -0,0 +1,17 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use polkadot_procmacro_overseer_subsystems_gen::AllSubsystemsGen;
|
||||
|
||||
#[derive(Clone, AllSubsystemsGen)]
|
||||
struct AllSubsystems<A, B> {
|
||||
a: A,
|
||||
b: B,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let all = AllSubsystems::<u8, u16> {
|
||||
a: 0u8,
|
||||
b: 1u16,
|
||||
};
|
||||
let _all: AllSubsystems<_,_> = all.replace_a::<u32>(777_777u32);
|
||||
}
|
||||
Reference in New Issue
Block a user