@@ -102,12 +102,73 @@ impl Step {
102102
103103 /// Expands generated code of this [`Step`] definition.
104104 fn expand ( self ) -> syn:: Result < TokenStream > {
105- let is_regex = matches ! ( self . attr_arg, AttributeArgument :: Regex ( _) ) ;
106-
107105 let func = & self . func ;
108106 let func_name = & func. sig . ident ;
109107
110- let ( func_args, addon_parsing) = if is_regex {
108+ let world = parse_world_from_args ( & self . func . sig ) ?;
109+ let constructor_method = self . constructor_method ( ) ;
110+ let ( func_args, addon_parsing) =
111+ self . fn_arguments_and_additional_parsing ( ) ?;
112+
113+ let step_matcher = self . attr_arg . regex_literal ( ) . value ( ) ;
114+ let caller_name =
115+ format_ident ! ( "__cucumber_{}_{}" , self . attr_name, func_name) ;
116+ let awaiting = if func. sig . asyncness . is_some ( ) {
117+ quote ! { . await }
118+ } else {
119+ quote ! { }
120+ } ;
121+ let step_caller = quote ! {
122+ {
123+ #[ automatically_derived]
124+ fn #caller_name<' w>(
125+ __cucumber_world: & ' w mut #world,
126+ __cucumber_ctx: :: cucumber:: step:: Context ,
127+ ) -> :: cucumber:: codegen:: LocalBoxFuture <' w, ( ) > {
128+ let f = async move {
129+ #addon_parsing
130+ #func_name( __cucumber_world, #func_args) #awaiting;
131+ } ;
132+ :: std:: boxed:: Box :: pin( f)
133+ }
134+
135+ #caller_name
136+ }
137+ } ;
138+
139+ Ok ( quote ! {
140+ #func
141+
142+ #[ automatically_derived]
143+ :: cucumber:: codegen:: submit!(
144+ #![ crate = :: cucumber:: codegen] {
145+ <#world as :: cucumber:: codegen:: WorldInventory <
146+ _, _, _,
147+ >>:: #constructor_method(
148+ :: cucumber:: step:: Location {
149+ path: :: std:: convert:: From :: from( :: std:: file!( ) ) ,
150+ line: :: std:: line!( ) ,
151+ column: :: std:: column!( ) ,
152+ } ,
153+ :: cucumber:: codegen:: Regex :: new( #step_matcher)
154+ . unwrap( ) ,
155+ #step_caller,
156+ )
157+ }
158+ ) ;
159+ } )
160+ }
161+
162+ /// Generates code that prepares function's arguments basing on
163+ /// [`AttributeArgument`] and additional parsing if it's an
164+ /// [`AttributeArgument::Regex`].
165+ fn fn_arguments_and_additional_parsing (
166+ & self ,
167+ ) -> syn:: Result < ( TokenStream , Option < TokenStream > ) > {
168+ let is_regex = matches ! ( self . attr_arg, AttributeArgument :: Regex ( _) ) ;
169+ let func = & self . func ;
170+
171+ if is_regex {
111172 if let Some ( elem_ty) = find_first_slice ( & func. sig ) {
112173 let addon_parsing = Some ( quote ! {
113174 let __cucumber_matches = __cucumber_ctx
@@ -131,7 +192,7 @@ impl Step {
131192 . map ( |arg| self . borrow_step_or_slice ( arg) )
132193 . collect :: < Result < TokenStream , _ > > ( ) ?;
133194
134- ( func_args, addon_parsing)
195+ Ok ( ( func_args, addon_parsing) )
135196 } else {
136197 #[ allow( clippy:: redundant_closure_for_method_calls) ]
137198 let ( idents, parsings) : ( Vec < _ > , Vec < _ > ) =
@@ -154,62 +215,16 @@ impl Step {
154215 #( #idents, ) *
155216 } ;
156217
157- ( func_args, addon_parsing)
218+ Ok ( ( func_args, addon_parsing) )
158219 }
159220 } else if self . step_arg_name . is_some ( ) {
160- (
221+ Ok ( (
161222 quote ! { :: std:: borrow:: Borrow :: borrow( & __cucumber_ctx. step) , } ,
162223 None ,
163- )
164- } else {
165- ( TokenStream :: default ( ) , None )
166- } ;
167-
168- let world = parse_world_from_args ( & self . func . sig ) ?;
169- let constructor_method = self . constructor_method ( ) ;
170-
171- let step_matcher = self . attr_arg . regex_literal ( ) . value ( ) ;
172- let caller_name =
173- format_ident ! ( "__cucumber_{}_{}" , self . attr_name, func_name) ;
174- let awaiting = if func. sig . asyncness . is_some ( ) {
175- quote ! { . await }
224+ ) )
176225 } else {
177- quote ! { }
178- } ;
179- let step_caller = quote ! {
180- {
181- #[ automatically_derived]
182- fn #caller_name<' w>(
183- __cucumber_world: & ' w mut #world,
184- __cucumber_ctx: :: cucumber:: step:: Context ,
185- ) -> :: cucumber:: codegen:: LocalBoxFuture <' w, ( ) > {
186- let f = async move {
187- #addon_parsing
188- #func_name( __cucumber_world, #func_args) #awaiting;
189- } ;
190- :: std:: boxed:: Box :: pin( f)
191- }
192-
193- #caller_name
194- }
195- } ;
196-
197- Ok ( quote ! {
198- #func
199-
200- #[ automatically_derived]
201- :: cucumber:: codegen:: submit!(
202- #![ crate = :: cucumber:: codegen] {
203- <#world as :: cucumber:: codegen:: WorldInventory <
204- _, _, _,
205- >>:: #constructor_method(
206- :: cucumber:: codegen:: Regex :: new( #step_matcher)
207- . unwrap( ) ,
208- #step_caller,
209- )
210- }
211- ) ;
212- } )
226+ Ok ( ( TokenStream :: default ( ) , None ) )
227+ }
213228 }
214229
215230 /// Composes a name of the `cucumber::codegen::WorldInventory` method to
0 commit comments