Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 057f2af

Browse files
authored
Implement #[pallet::composite_enum] (#13722)
* Implement #[pallet::hold_reason] * Appease clippy * cargo fmt * Update test expectations * Update test expectations * Support composite_enum attribute instead * Update test expectations * Change hold_reason to composite_enum * Add UI test for unsupported identifier when using composite_enum * Fix comment * Add documentation for pallet::composable_enum * More docs * cargo fmt
1 parent 1f09739 commit 057f2af

26 files changed

+682
-11
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License
17+
18+
use crate::construct_runtime::{parse::PalletPath, Pallet};
19+
use proc_macro2::{Ident, TokenStream};
20+
use quote::quote;
21+
22+
pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
23+
let mut conversion_fns = Vec::new();
24+
let mut freeze_reason_variants = Vec::new();
25+
for decl in pallet_decls {
26+
if let Some(_) = decl.find_part("FreezeReason") {
27+
let variant_name = &decl.name;
28+
let path = &decl.path;
29+
let index = decl.index;
30+
31+
conversion_fns.push(expand_conversion_fn(path, variant_name));
32+
33+
freeze_reason_variants.push(expand_variant(index, path, variant_name));
34+
}
35+
}
36+
37+
quote! {
38+
#[derive(
39+
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
40+
#scrate::codec::Encode, #scrate::codec::Decode, #scrate::codec::MaxEncodedLen,
41+
#scrate::scale_info::TypeInfo,
42+
#scrate::RuntimeDebug,
43+
)]
44+
pub enum RuntimeFreezeReason {
45+
#( #freeze_reason_variants )*
46+
}
47+
48+
#( #conversion_fns )*
49+
}
50+
}
51+
52+
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
53+
quote! {
54+
impl From<#path::FreezeReason> for RuntimeFreezeReason {
55+
fn from(hr: #path::FreezeReason) -> Self {
56+
RuntimeFreezeReason::#variant_name(hr)
57+
}
58+
}
59+
}
60+
}
61+
62+
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
63+
quote! {
64+
#[codec(index = #index)]
65+
#variant_name(#path::FreezeReason),
66+
}
67+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License
17+
18+
use crate::construct_runtime::{parse::PalletPath, Pallet};
19+
use proc_macro2::{Ident, TokenStream};
20+
use quote::quote;
21+
22+
pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
23+
let mut conversion_fns = Vec::new();
24+
let mut hold_reason_variants = Vec::new();
25+
for decl in pallet_decls {
26+
if let Some(_) = decl.find_part("HoldReason") {
27+
let variant_name = &decl.name;
28+
let path = &decl.path;
29+
let index = decl.index;
30+
31+
conversion_fns.push(expand_conversion_fn(path, variant_name));
32+
33+
hold_reason_variants.push(expand_variant(index, path, variant_name));
34+
}
35+
}
36+
37+
quote! {
38+
#[derive(
39+
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
40+
#scrate::codec::Encode, #scrate::codec::Decode, #scrate::codec::MaxEncodedLen,
41+
#scrate::scale_info::TypeInfo,
42+
#scrate::RuntimeDebug,
43+
)]
44+
pub enum RuntimeHoldReason {
45+
#( #hold_reason_variants )*
46+
}
47+
48+
#( #conversion_fns )*
49+
}
50+
}
51+
52+
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
53+
quote! {
54+
impl From<#path::HoldReason> for RuntimeHoldReason {
55+
fn from(hr: #path::HoldReason) -> Self {
56+
RuntimeHoldReason::#variant_name(hr)
57+
}
58+
}
59+
}
60+
}
61+
62+
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
63+
quote! {
64+
#[codec(index = #index)]
65+
#variant_name(#path::HoldReason),
66+
}
67+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License
17+
18+
use crate::construct_runtime::{parse::PalletPath, Pallet};
19+
use proc_macro2::{Ident, TokenStream};
20+
use quote::quote;
21+
22+
pub fn expand_outer_lock_id(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
23+
let mut conversion_fns = Vec::new();
24+
let mut lock_id_variants = Vec::new();
25+
for decl in pallet_decls {
26+
if let Some(_) = decl.find_part("LockId") {
27+
let variant_name = &decl.name;
28+
let path = &decl.path;
29+
let index = decl.index;
30+
31+
conversion_fns.push(expand_conversion_fn(path, variant_name));
32+
33+
lock_id_variants.push(expand_variant(index, path, variant_name));
34+
}
35+
}
36+
37+
quote! {
38+
#[derive(
39+
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
40+
#scrate::codec::Encode, #scrate::codec::Decode, #scrate::codec::MaxEncodedLen,
41+
#scrate::scale_info::TypeInfo,
42+
#scrate::RuntimeDebug,
43+
)]
44+
pub enum RuntimeLockId {
45+
#( #lock_id_variants )*
46+
}
47+
48+
#( #conversion_fns )*
49+
}
50+
}
51+
52+
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
53+
quote! {
54+
impl From<#path::LockId> for RuntimeLockId {
55+
fn from(hr: #path::LockId) -> Self {
56+
RuntimeLockId::#variant_name(hr)
57+
}
58+
}
59+
}
60+
}
61+
62+
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
63+
quote! {
64+
#[codec(index = #index)]
65+
#variant_name(#path::LockId),
66+
}
67+
}

frame/support/procedural/src/construct_runtime/expand/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,23 @@
1818
mod call;
1919
mod config;
2020
mod event;
21+
mod freeze_reason;
22+
mod hold_reason;
2123
mod inherent;
24+
mod lock_id;
2225
mod metadata;
2326
mod origin;
27+
mod slash_reason;
2428
mod unsigned;
2529

2630
pub use call::expand_outer_dispatch;
2731
pub use config::expand_outer_config;
2832
pub use event::expand_outer_event;
33+
pub use freeze_reason::expand_outer_freeze_reason;
34+
pub use hold_reason::expand_outer_hold_reason;
2935
pub use inherent::expand_outer_inherent;
36+
pub use lock_id::expand_outer_lock_id;
3037
pub use metadata::expand_runtime_metadata;
3138
pub use origin::expand_outer_origin;
39+
pub use slash_reason::expand_outer_slash_reason;
3240
pub use unsigned::expand_outer_validate_unsigned;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License
17+
18+
use crate::construct_runtime::{parse::PalletPath, Pallet};
19+
use proc_macro2::{Ident, TokenStream};
20+
use quote::quote;
21+
22+
pub fn expand_outer_slash_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
23+
let mut conversion_fns = Vec::new();
24+
let mut slash_reason_variants = Vec::new();
25+
for decl in pallet_decls {
26+
if let Some(_) = decl.find_part("SlashReason") {
27+
let variant_name = &decl.name;
28+
let path = &decl.path;
29+
let index = decl.index;
30+
31+
conversion_fns.push(expand_conversion_fn(path, variant_name));
32+
33+
slash_reason_variants.push(expand_variant(index, path, variant_name));
34+
}
35+
}
36+
37+
quote! {
38+
#[derive(
39+
Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
40+
#scrate::codec::Encode, #scrate::codec::Decode, #scrate::codec::MaxEncodedLen,
41+
#scrate::scale_info::TypeInfo,
42+
#scrate::RuntimeDebug,
43+
)]
44+
pub enum RuntimeSlashReason {
45+
#( #slash_reason_variants )*
46+
}
47+
48+
#( #conversion_fns )*
49+
}
50+
}
51+
52+
fn expand_conversion_fn(path: &PalletPath, variant_name: &Ident) -> TokenStream {
53+
quote! {
54+
impl From<#path::SlashReason> for RuntimeSlashReason {
55+
fn from(hr: #path::SlashReason) -> Self {
56+
RuntimeSlashReason::#variant_name(hr)
57+
}
58+
}
59+
}
60+
}
61+
62+
fn expand_variant(index: u8, path: &PalletPath, variant_name: &Ident) -> TokenStream {
63+
quote! {
64+
#[codec(index = #index)]
65+
#variant_name(#path::SlashReason),
66+
}
67+
}

frame/support/procedural/src/construct_runtime/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ fn construct_runtime_final_expansion(
268268
let inherent =
269269
expand::expand_outer_inherent(&name, &block, &unchecked_extrinsic, &pallets, &scrate);
270270
let validate_unsigned = expand::expand_outer_validate_unsigned(&name, &pallets, &scrate);
271+
let freeze_reason = expand::expand_outer_freeze_reason(&pallets, &scrate);
272+
let hold_reason = expand::expand_outer_hold_reason(&pallets, &scrate);
273+
let lock_id = expand::expand_outer_lock_id(&pallets, &scrate);
274+
let slash_reason = expand::expand_outer_slash_reason(&pallets, &scrate);
271275
let integrity_test = decl_integrity_test(&scrate);
272276
let static_assertions = decl_static_assertions(&name, &pallets, &scrate);
273277

@@ -310,6 +314,14 @@ fn construct_runtime_final_expansion(
310314

311315
#validate_unsigned
312316

317+
#freeze_reason
318+
319+
#hold_reason
320+
321+
#lock_id
322+
323+
#slash_reason
324+
313325
#integrity_test
314326

315327
#static_assertions

frame/support/procedural/src/construct_runtime/parse.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ mod keyword {
3838
syn::custom_keyword!(Origin);
3939
syn::custom_keyword!(Inherent);
4040
syn::custom_keyword!(ValidateUnsigned);
41+
syn::custom_keyword!(FreezeReason);
42+
syn::custom_keyword!(HoldReason);
43+
syn::custom_keyword!(LockId);
44+
syn::custom_keyword!(SlashReason);
4145
syn::custom_keyword!(exclude_parts);
4246
syn::custom_keyword!(use_parts);
4347
}
@@ -370,6 +374,10 @@ pub enum PalletPartKeyword {
370374
Origin(keyword::Origin),
371375
Inherent(keyword::Inherent),
372376
ValidateUnsigned(keyword::ValidateUnsigned),
377+
FreezeReason(keyword::FreezeReason),
378+
HoldReason(keyword::HoldReason),
379+
LockId(keyword::LockId),
380+
SlashReason(keyword::SlashReason),
373381
}
374382

375383
impl Parse for PalletPartKeyword {
@@ -392,6 +400,14 @@ impl Parse for PalletPartKeyword {
392400
Ok(Self::Inherent(input.parse()?))
393401
} else if lookahead.peek(keyword::ValidateUnsigned) {
394402
Ok(Self::ValidateUnsigned(input.parse()?))
403+
} else if lookahead.peek(keyword::FreezeReason) {
404+
Ok(Self::FreezeReason(input.parse()?))
405+
} else if lookahead.peek(keyword::HoldReason) {
406+
Ok(Self::HoldReason(input.parse()?))
407+
} else if lookahead.peek(keyword::LockId) {
408+
Ok(Self::LockId(input.parse()?))
409+
} else if lookahead.peek(keyword::SlashReason) {
410+
Ok(Self::SlashReason(input.parse()?))
395411
} else {
396412
Err(lookahead.error())
397413
}
@@ -410,6 +426,10 @@ impl PalletPartKeyword {
410426
Self::Origin(_) => "Origin",
411427
Self::Inherent(_) => "Inherent",
412428
Self::ValidateUnsigned(_) => "ValidateUnsigned",
429+
Self::FreezeReason(_) => "FreezeReason",
430+
Self::HoldReason(_) => "HoldReason",
431+
Self::LockId(_) => "LockId",
432+
Self::SlashReason(_) => "SlashReason",
413433
}
414434
}
415435

@@ -435,6 +455,10 @@ impl Spanned for PalletPartKeyword {
435455
Self::Origin(inner) => inner.span(),
436456
Self::Inherent(inner) => inner.span(),
437457
Self::ValidateUnsigned(inner) => inner.span(),
458+
Self::FreezeReason(inner) => inner.span(),
459+
Self::HoldReason(inner) => inner.span(),
460+
Self::LockId(inner) => inner.span(),
461+
Self::SlashReason(inner) => inner.span(),
438462
}
439463
}
440464
}

0 commit comments

Comments
 (0)