frame_support_procedural/runtime/parse/
pallet_decl.rs
1use syn::{Ident, PathArguments};
19
20#[derive(Debug, Clone)]
22pub struct PalletDeclaration {
23 pub name: Ident,
25 pub path: syn::Path,
27 pub pallet_segment: Option<syn::PathSegment>,
29 pub runtime_param: Option<Ident>,
32 pub instance: Option<Ident>,
35}
36
37impl PalletDeclaration {
38 pub fn try_from(
39 _attr_span: proc_macro2::Span,
40 item: &syn::ItemType,
41 path: &syn::Path,
42 ) -> syn::Result<Self> {
43 let name = item.ident.clone();
44
45 let mut path = path.clone();
46
47 let mut pallet_segment = None;
48 let mut runtime_param = None;
49 let mut instance = None;
50 if let Some(segment) = path.segments.iter_mut().find(|seg| !seg.arguments.is_empty()) {
51 if let PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
52 args, ..
53 }) = segment.arguments.clone()
54 {
55 if segment.ident == "Pallet" {
56 let mut segment = segment.clone();
57 segment.arguments = PathArguments::None;
58 pallet_segment = Some(segment.clone());
59 }
60 let mut args_iter = args.iter();
61 if let Some(syn::GenericArgument::Type(syn::Type::Path(arg_path))) =
62 args_iter.next()
63 {
64 let ident = arg_path.path.require_ident()?.clone();
65 if segment.ident == "Pallet" {
66 runtime_param = Some(ident);
67 if let Some(syn::GenericArgument::Type(syn::Type::Path(arg_path))) =
68 args_iter.next()
69 {
70 instance = Some(arg_path.path.require_ident()?.clone());
71 }
72 } else {
73 instance = Some(ident);
74 segment.arguments = PathArguments::None;
75 }
76 }
77 }
78 }
79
80 if pallet_segment.is_some() {
81 path = syn::Path {
82 leading_colon: None,
83 segments: path
84 .segments
85 .iter()
86 .filter(|seg| seg.arguments.is_empty())
87 .cloned()
88 .collect(),
89 };
90 }
91
92 Ok(Self { name, path, pallet_segment, runtime_param, instance })
93 }
94}
95
96#[test]
97fn declaration_works() {
98 use syn::parse_quote;
99
100 let decl: PalletDeclaration = PalletDeclaration::try_from(
101 proc_macro2::Span::call_site(),
102 &parse_quote! { pub type System = frame_system; },
103 &parse_quote! { frame_system },
104 )
105 .expect("Failed to parse pallet declaration");
106
107 assert_eq!(decl.name, "System");
108 assert_eq!(decl.path, parse_quote! { frame_system });
109 assert_eq!(decl.pallet_segment, None);
110 assert_eq!(decl.runtime_param, None);
111 assert_eq!(decl.instance, None);
112}
113
114#[test]
115fn declaration_works_with_instance() {
116 use syn::parse_quote;
117
118 let decl: PalletDeclaration = PalletDeclaration::try_from(
119 proc_macro2::Span::call_site(),
120 &parse_quote! { pub type System = frame_system<Instance1>; },
121 &parse_quote! { frame_system<Instance1> },
122 )
123 .expect("Failed to parse pallet declaration");
124
125 assert_eq!(decl.name, "System");
126 assert_eq!(decl.path, parse_quote! { frame_system });
127 assert_eq!(decl.pallet_segment, None);
128 assert_eq!(decl.runtime_param, None);
129 assert_eq!(decl.instance, Some(parse_quote! { Instance1 }));
130}
131
132#[test]
133fn declaration_works_with_pallet() {
134 use syn::parse_quote;
135
136 let decl: PalletDeclaration = PalletDeclaration::try_from(
137 proc_macro2::Span::call_site(),
138 &parse_quote! { pub type System = frame_system::Pallet<Runtime>; },
139 &parse_quote! { frame_system::Pallet<Runtime> },
140 )
141 .expect("Failed to parse pallet declaration");
142
143 assert_eq!(decl.name, "System");
144 assert_eq!(decl.path, parse_quote! { frame_system });
145
146 let segment: syn::PathSegment =
147 syn::PathSegment { ident: parse_quote! { Pallet }, arguments: PathArguments::None };
148 assert_eq!(decl.pallet_segment, Some(segment));
149 assert_eq!(decl.runtime_param, Some(parse_quote! { Runtime }));
150 assert_eq!(decl.instance, None);
151}
152
153#[test]
154fn declaration_works_with_pallet_and_instance() {
155 use syn::parse_quote;
156
157 let decl: PalletDeclaration = PalletDeclaration::try_from(
158 proc_macro2::Span::call_site(),
159 &parse_quote! { pub type System = frame_system::Pallet<Runtime, Instance1>; },
160 &parse_quote! { frame_system::Pallet<Runtime, Instance1> },
161 )
162 .expect("Failed to parse pallet declaration");
163
164 assert_eq!(decl.name, "System");
165 assert_eq!(decl.path, parse_quote! { frame_system });
166
167 let segment: syn::PathSegment =
168 syn::PathSegment { ident: parse_quote! { Pallet }, arguments: PathArguments::None };
169 assert_eq!(decl.pallet_segment, Some(segment));
170 assert_eq!(decl.runtime_param, Some(parse_quote! { Runtime }));
171 assert_eq!(decl.instance, Some(parse_quote! { Instance1 }));
172}