frame_support_procedural/construct_runtime/expand/
task.rs1use crate::construct_runtime::Pallet;
19use proc_macro2::{Ident, TokenStream as TokenStream2};
20use quote::quote;
21
22pub fn expand_outer_task(
24 runtime_name: &Ident,
25 pallet_decls: &[Pallet],
26 scrate: &TokenStream2,
27) -> TokenStream2 {
28 let mut from_impls = Vec::new();
29 let mut task_variants = Vec::new();
30 let mut variant_names = Vec::new();
31 let mut task_types = Vec::new();
32 let mut cfg_attrs = Vec::new();
33 for decl in pallet_decls {
34 if decl.find_part("Task").is_none() {
35 continue
36 }
37
38 let variant_name = &decl.name;
39 let path = &decl.path;
40 let index = decl.index;
41 let instance = decl.instance.as_ref().map(|instance| quote!(, #path::#instance));
42 let task_type = quote!(#path::Task<#runtime_name #instance>);
43
44 let attr = decl.get_attributes();
45
46 from_impls.push(quote! {
47 #attr
48 impl From<#task_type> for RuntimeTask {
49 fn from(hr: #task_type) -> Self {
50 RuntimeTask::#variant_name(hr)
51 }
52 }
53
54 #attr
55 impl TryInto<#task_type> for RuntimeTask {
56 type Error = ();
57
58 fn try_into(self) -> Result<#task_type, Self::Error> {
59 match self {
60 RuntimeTask::#variant_name(hr) => Ok(hr),
61 _ => Err(()),
62 }
63 }
64 }
65 });
66
67 task_variants.push(quote! {
68 #attr
69 #[codec(index = #index)]
70 #variant_name(#task_type),
71 });
72
73 variant_names.push(quote!(#variant_name));
74
75 task_types.push(task_type);
76
77 cfg_attrs.push(attr);
78 }
79
80 let prelude = quote!(#scrate::traits::tasks::__private);
81
82 const INCOMPLETE_MATCH_QED: &'static str =
83 "cannot have an instantiated RuntimeTask without some Task variant in the runtime. QED";
84
85 let output = quote! {
86 #[derive(
88 Clone, Eq, PartialEq,
89 #scrate::__private::codec::Encode,
90 #scrate::__private::codec::Decode,
91 #scrate::__private::codec::DecodeWithMemTracking,
92 #scrate::__private::scale_info::TypeInfo,
93 #scrate::__private::RuntimeDebug,
94 )]
95 pub enum RuntimeTask {
96 #( #task_variants )*
97 }
98
99 #[automatically_derived]
100 impl #scrate::traits::Task for RuntimeTask {
101 type Enumeration = #prelude::IntoIter<RuntimeTask>;
102
103 fn is_valid(&self) -> bool {
104 match self {
105 #(
106 #cfg_attrs
107 RuntimeTask::#variant_names(val) => val.is_valid(),
108 )*
109 _ => unreachable!(#INCOMPLETE_MATCH_QED),
110 }
111 }
112
113 fn run(&self) -> Result<(), #scrate::traits::tasks::__private::DispatchError> {
114 match self {
115 #(
116 #cfg_attrs
117 RuntimeTask::#variant_names(val) => val.run(),
118 )*
119 _ => unreachable!(#INCOMPLETE_MATCH_QED),
120 }
121 }
122
123 fn weight(&self) -> #scrate::pallet_prelude::Weight {
124 match self {
125 #(
126 #cfg_attrs
127 RuntimeTask::#variant_names(val) => val.weight(),
128 )*
129 _ => unreachable!(#INCOMPLETE_MATCH_QED),
130 }
131 }
132
133 fn task_index(&self) -> u32 {
134 match self {
135 #(
136 #cfg_attrs
137 RuntimeTask::#variant_names(val) => val.task_index(),
138 )*
139 _ => unreachable!(#INCOMPLETE_MATCH_QED),
140 }
141 }
142
143 fn iter() -> Self::Enumeration {
144 let mut all_tasks = Vec::new();
145 #(
146 #cfg_attrs
147 all_tasks.extend(<#task_types>::iter().map(RuntimeTask::from).collect::<Vec<_>>());
148 )*
149 all_tasks.into_iter()
150 }
151 }
152
153 #( #from_impls )*
154 };
155
156 output
157}