@@ -93,29 +93,10 @@ struct VariantInfo {
9393 catch_all : bool ,
9494}
9595
96- pub ( super ) fn handle_enum ( item : ItemEnum ) -> syn:: Result < proc_macro2:: TokenStream > {
97- if !item. generics . params . is_empty ( ) {
98- return Err ( Error :: new (
99- item. span ( ) ,
100- "A new type oparg cannot be generic." ,
101- ) ) ;
102- }
103-
104- let ItemEnum {
105- attrs,
106- vis,
107- enum_token,
108- ident,
109- generics : _,
110- brace_token : _,
111- variants,
112- } = item. clone ( ) ;
113-
114- let mut variants_info = vec ! [ ] ;
115- for variant in & variants {
116- let ident = variant. ident . clone ( ) ;
117- let discriminant = variant. discriminant . as_ref ( ) . map ( |( _, expr) | expr. clone ( ) ) ;
96+ impl TryFrom < syn:: Variant > for VariantInfo {
97+ type Error = syn:: Error ;
11898
99+ fn try_from ( variant : syn:: Variant ) -> Result < Self , Self :: Error > {
119100 let mut display = None ;
120101 let mut catch_all = false ;
121102 for attr in & variant. attrs {
@@ -137,13 +118,55 @@ pub(super) fn handle_enum(item: ItemEnum) -> syn::Result<proc_macro2::TokenStrea
137118 } ) ?
138119 }
139120
140- variants_info. push ( VariantInfo {
121+ let ident = variant. ident . clone ( ) ;
122+ let discriminant = variant. discriminant . as_ref ( ) . map ( |( _, expr) | expr. clone ( ) ) ;
123+
124+ if catch_all && display. is_some ( ) {
125+ return Err ( Error :: new (
126+ ident. span ( ) ,
127+ r#"Cannot define both `#[oparg(catch_all)`] and `#[oparg(display = "...")]` on the same variant"# ,
128+ ) ) ;
129+ }
130+
131+ if discriminant. is_none ( ) && !catch_all {
132+ return Err ( Error :: new (
133+ ident. span ( ) ,
134+ "Is a variant without an assigned value" ,
135+ ) ) ;
136+ }
137+
138+ Ok ( Self {
141139 ident,
142140 discriminant,
143141 display,
144142 catch_all,
145143 } )
146144 }
145+ }
146+
147+ pub ( super ) fn handle_enum ( item : ItemEnum ) -> syn:: Result < proc_macro2:: TokenStream > {
148+ if !item. generics . params . is_empty ( ) {
149+ return Err ( Error :: new (
150+ item. span ( ) ,
151+ "A new type oparg cannot be generic." ,
152+ ) ) ;
153+ }
154+
155+ let ItemEnum {
156+ attrs,
157+ vis,
158+ enum_token,
159+ ident,
160+ generics : _,
161+ brace_token : _,
162+ variants,
163+ } = item. clone ( ) ;
164+
165+ let mut variants_info = variants
166+ . iter ( )
167+ . cloned ( )
168+ . map ( VariantInfo :: try_from)
169+ . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
147170
148171 let catch_all = variants_info. pop_if ( |info| info. catch_all ) ;
149172
@@ -155,26 +178,6 @@ pub(super) fn handle_enum(item: ItemEnum) -> syn::Result<proc_macro2::TokenStrea
155178 ) ) ;
156179 } ;
157180
158- match catch_all {
159- Some ( vinfo) if vinfo. display . is_some ( ) => {
160- return Err ( Error :: new (
161- vinfo. ident . span ( ) ,
162- r#"Cannot define both `#[oparg(catch_all)`] and `#[oparg(display = "...")]` on the same variant"# ,
163- ) ) ;
164- }
165- _ => { }
166- } ;
167-
168- // Ensure all variants has a discriminant.
169- for vinfo in & variants_info {
170- if vinfo. discriminant . is_none ( ) {
171- return Err ( Error :: new (
172- vinfo. ident . span ( ) ,
173- "Is a variant without an assigned value" ,
174- ) ) ;
175- }
176- }
177-
178181 let variants_def = variants. iter ( ) . cloned ( ) . map ( |mut variant| {
179182 // Don't assign value. Enables more optimizations by the compiler.
180183 variant. discriminant = None ;
0 commit comments