frame_support_procedural/pallet/parse/
error.rs1use super::helper;
19use crate::deprecation::extract_or_return_allow_attrs;
20use quote::ToTokens;
21use syn::{spanned::Spanned, Fields};
22
23mod keyword {
25 syn::custom_keyword!(Error);
26}
27
28pub struct VariantField {
30 pub is_named: bool,
32}
33
34pub struct VariantDef {
36 pub ident: syn::Ident,
38 pub field: Option<VariantField>,
40 pub cfg_attrs: Vec<syn::Attribute>,
42 pub maybe_allow_attrs: Vec<syn::Attribute>,
44}
45
46pub struct ErrorDef {
49 pub index: usize,
51 pub variants: Vec<VariantDef>,
53 pub instances: Vec<helper::InstanceUsage>,
55 pub error: keyword::Error,
57 pub attr_span: proc_macro2::Span,
59}
60
61impl ErrorDef {
62 pub fn try_from(
63 attr_span: proc_macro2::Span,
64 index: usize,
65 item: &mut syn::Item,
66 ) -> syn::Result<Self> {
67 let item = if let syn::Item::Enum(item) = item {
68 item
69 } else {
70 return Err(syn::Error::new(item.span(), "Invalid pallet::error, expected item enum"))
71 };
72 if !matches!(item.vis, syn::Visibility::Public(_)) {
73 let msg = "Invalid pallet::error, `Error` must be public";
74 return Err(syn::Error::new(item.span(), msg))
75 }
76
77 crate::deprecation::prevent_deprecation_attr_on_outer_enum(&item.attrs)?;
78
79 let instances =
80 vec![helper::check_type_def_gen_no_bounds(&item.generics, item.ident.span())?];
81
82 if item.generics.where_clause.is_some() {
83 let msg = "Invalid pallet::error, where clause is not allowed on pallet error item";
84 return Err(syn::Error::new(item.generics.where_clause.as_ref().unwrap().span(), msg))
85 }
86
87 let error = syn::parse2::<keyword::Error>(item.ident.to_token_stream())?;
88
89 let variants = item
90 .variants
91 .iter()
92 .map(|variant| {
93 let field_ty = match &variant.fields {
94 Fields::Unit => None,
95 Fields::Named(_) => Some(VariantField { is_named: true }),
96 Fields::Unnamed(_) => Some(VariantField { is_named: false }),
97 };
98
99 match &variant.discriminant {
100 None |
101 Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(_), .. }))) => {},
102 Some((_, expr)) => {
103 let msg = "Invalid pallet::error, only integer discriminants are supported";
104 return Err(syn::Error::new(expr.span(), msg))
105 },
106 }
107 let cfg_attrs: Vec<syn::Attribute> = helper::get_item_cfg_attrs(&variant.attrs);
108 let maybe_allow_attrs = extract_or_return_allow_attrs(&variant.attrs).collect();
109
110 Ok(VariantDef {
111 ident: variant.ident.clone(),
112 field: field_ty,
113 cfg_attrs,
114 maybe_allow_attrs,
115 })
116 })
117 .collect::<Result<_, _>>()?;
118
119 Ok(ErrorDef { attr_span, index, variants, instances, error })
120 }
121}