Adds instance support for composite enums (#1857)

Fixes https://github.com/paritytech/polkadot-sdk/issues/1839

Currently, `composite_enum`s do not support pallet instances. This PR
allows the following:
```rust
	#[pallet::composite_enum]
	pub enum HoldReason<I: 'static = ()> {
		SomeHoldReason
	}
```

### Todo

- [x]  UI Test
This commit is contained in:
gupnik
2023-10-13 07:48:51 +02:00
committed by GitHub
parent d2fc1d7c91
commit 6b27dad359
11 changed files with 264 additions and 93 deletions
@@ -0,0 +1,70 @@
// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License
use crate::construct_runtime::parse::PalletPath;
use proc_macro2::{Ident, TokenStream};
use quote::quote;
pub(crate) fn expand_conversion_fn(
composite_name: &str,
path: &PalletPath,
instance: Option<&Ident>,
variant_name: &Ident,
) -> TokenStream {
let composite_name = quote::format_ident!("{}", composite_name);
let runtime_composite_name = quote::format_ident!("Runtime{}", composite_name);
if let Some(inst) = instance {
quote! {
impl From<#path::#composite_name<#path::#inst>> for #runtime_composite_name {
fn from(hr: #path::#composite_name<#path::#inst>) -> Self {
#runtime_composite_name::#variant_name(hr)
}
}
}
} else {
quote! {
impl From<#path::#composite_name> for #runtime_composite_name {
fn from(hr: #path::#composite_name) -> Self {
#runtime_composite_name::#variant_name(hr)
}
}
}
}
}
pub(crate) fn expand_variant(
composite_name: &str,
index: u8,
path: &PalletPath,
instance: Option<&Ident>,
variant_name: &Ident,
) -> TokenStream {
let composite_name = quote::format_ident!("{}", composite_name);
if let Some(inst) = instance {
quote! {
#[codec(index = #index)]
#variant_name(#path::#composite_name<#path::#inst>),
}
} else {
quote! {
#[codec(index = #index)]
#variant_name(#path::#composite_name),
}
}
}
@@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License
use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;
pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
@@ -27,17 +28,29 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();
conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"FreezeReason",
path,
instance,
variant_name,
));
freeze_reason_variants.push(expand_variant(index, path, variant_name));
freeze_reason_variants.push(composite_helper::expand_variant(
"FreezeReason",
index,
path,
instance,
variant_name,
));
}
}
quote! {
/// A reason for placing a freeze on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
@@ -49,20 +62,3 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
#( #conversion_fns )*
}
}
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::FreezeReason> for RuntimeFreezeReason {
fn from(hr: #path::FreezeReason) -> Self {
RuntimeFreezeReason::#variant_name(hr)
}
}
}
}
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::FreezeReason),
}
}
@@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License
use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;
pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
@@ -27,17 +28,29 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();
conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"HoldReason",
path,
instance,
variant_name,
));
hold_reason_variants.push(expand_variant(index, path, variant_name));
hold_reason_variants.push(composite_helper::expand_variant(
"HoldReason",
index,
path,
instance,
variant_name,
));
}
}
quote! {
/// A reason for placing a hold on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
@@ -49,20 +62,3 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
#( #conversion_fns )*
}
}
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::HoldReason> for RuntimeHoldReason {
fn from(hr: #path::HoldReason) -> Self {
RuntimeHoldReason::#variant_name(hr)
}
}
}
}
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::HoldReason),
}
}
@@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License
use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;
pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
@@ -27,17 +28,29 @@ pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> To
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();
conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"LockId",
path,
instance,
variant_name,
));
lock_id_variants.push(expand_variant(index, path, variant_name));
lock_id_variants.push(composite_helper::expand_variant(
"LockId",
index,
path,
instance,
variant_name,
));
}
}
quote! {
/// An identifier for each lock placed on funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
@@ -49,20 +62,3 @@ pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> To
#( #conversion_fns )*
}
}
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::LockId> for RuntimeLockId {
fn from(hr: #path::LockId) -> Self {
RuntimeLockId::#variant_name(hr)
}
}
}
}
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::LockId),
}
}
@@ -16,6 +16,7 @@
// limitations under the License
mod call;
pub mod composite_helper;
mod config;
mod freeze_reason;
mod hold_reason;
@@ -15,8 +15,9 @@
// See the License for the specific language governing permissions and
// limitations under the License
use crate::construct_runtime::{parse::PalletPath, Pallet};
use proc_macro2::{Ident, TokenStream};
use super::composite_helper;
use crate::construct_runtime::Pallet;
use proc_macro2::TokenStream;
use quote::quote;
pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
@@ -27,17 +28,29 @@ pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
let variant_name = &decl.name;
let path = &decl.path;
let index = decl.index;
let instance = decl.instance.as_ref();
conversion_fns.push(expand_conversion_fn(path, variant_name));
conversion_fns.push(composite_helper::expand_conversion_fn(
"SlashReason",
path,
instance,
variant_name,
));
slash_reason_variants.push(expand_variant(index, path, variant_name));
slash_reason_variants.push(composite_helper::expand_variant(
"SlashReason",
index,
path,
instance,
variant_name,
));
}
}
quote! {
/// A reason for slashing funds.
#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
Copy, Clone, Eq, PartialEq,
#scrate::__private::codec::Encode, #scrate::__private::codec::Decode, #scrate::__private::codec::MaxEncodedLen,
#scrate::__private::scale_info::TypeInfo,
#scrate::__private::RuntimeDebug,
@@ -49,20 +62,3 @@ pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
#( #conversion_fns )*
}
}
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
impl From<#path::SlashReason> for RuntimeSlashReason {
fn from(hr: #path::SlashReason) -> Self {
RuntimeSlashReason::#variant_name(hr)
}
}
}
}
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
quote! {
#[codec(index = #index)]
#variant_name(#path::SlashReason),
}
}