Skip to content

Commit 2d18256

Browse files
dependabot[bot]ilslvtyranron
authored
Upgrade inventory to 0.2 (#158)
Additionally: - simplify code examples in docs with using `#[tokio::main]` macro Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ilya Solovyiov <[email protected]> Co-authored-by: Kai Ren <[email protected]>
1 parent ab430cc commit 2d18256

File tree

9 files changed

+153
-243
lines changed

9 files changed

+153
-243
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ structopt = "0.3.25"
5454

5555
# "macros" feature dependencies
5656
cucumber-codegen = { version = "0.11.0-dev", path = "./codegen", optional = true }
57-
inventory = { version = "0.1.10", optional = true }
57+
inventory = { version = "0.2", optional = true }
5858

5959
# "output-json" feature dependencies
6060
serde = { version = "1.0.103", features = ["derive"], optional = true }

codegen/src/attribute.rs

+44-21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
use std::mem;
1414

15+
use inflections::case::to_pascal_case;
1516
use proc_macro2::TokenStream;
1617
use quote::{format_ident, quote};
1718
use regex::{self, Regex};
@@ -101,7 +102,7 @@ impl Step {
101102
let func_name = &func.sig.ident;
102103

103104
let world = parse_world_from_args(&self.func.sig)?;
104-
let constructor_method = self.constructor_method();
105+
let step_type = self.step_type();
105106
let (func_args, addon_parsing) =
106107
self.fn_arguments_and_additional_parsing()?;
107108

@@ -129,30 +130,52 @@ impl Step {
129130
::std::boxed::Box::pin(f)
130131
}
131132

132-
#caller_name
133+
let f: ::cucumber::Step<#world> = #caller_name;
134+
f
133135
}
134136
};
135137

136138
Ok(quote! {
137139
#func
138140

139141
#[automatically_derived]
140-
::cucumber::codegen::submit!(
141-
#![crate = ::cucumber::codegen] {
142-
<#world as ::cucumber::codegen::WorldInventory<
143-
_, _, _,
144-
>>::#constructor_method(
145-
::cucumber::step::Location {
146-
path: ::std::convert::From::from(::std::file!()),
147-
line: ::std::line!(),
148-
column: ::std::column!(),
149-
},
150-
::cucumber::codegen::Regex::new(#step_matcher)
151-
.unwrap(),
152-
#step_caller,
153-
)
142+
::cucumber::codegen::submit!({
143+
// TODO: Remove this, once `#![feature(more_qualified_paths)]`
144+
// is stabilized:
145+
// https://github.com/rust-lang/rust/issues/86935
146+
type StepAlias =
147+
<#world as ::cucumber::codegen::WorldInventory>::#step_type;
148+
149+
StepAlias {
150+
loc: ::cucumber::step::Location {
151+
path: ::std::file!(),
152+
line: ::std::line!(),
153+
column: ::std::column!(),
154+
},
155+
regex: {
156+
// This hack exists, as `fn item` to `fn pointer`
157+
// coercion can be done inside `const`, but not
158+
// `const fn`.
159+
let lazy: ::cucumber::codegen::LazyRegex = || {
160+
static LAZY: ::cucumber::codegen::Lazy<
161+
::cucumber::codegen::Regex
162+
> = ::cucumber::codegen::Lazy::new(|| {
163+
::cucumber::codegen::Regex::new(#step_matcher)
164+
.unwrap()
165+
});
166+
LAZY.clone()
167+
};
168+
lazy
169+
},
170+
func: {
171+
// This hack exists, as `fn item` to `fn pointer`
172+
// coercion can be done inside `const`, but not
173+
// `const fn`.
174+
const F: ::cucumber::Step<#world> = #step_caller;
175+
F
176+
},
154177
}
155-
);
178+
});
156179
})
157180
}
158181

@@ -238,10 +261,10 @@ impl Step {
238261
}
239262
}
240263

241-
/// Composes a name of the `cucumber::codegen::WorldInventory` method to
242-
/// wire this [`Step`] with.
243-
fn constructor_method(&self) -> syn::Ident {
244-
format_ident!("new_{}", self.attr_name)
264+
/// Composes a name of the `cucumber::codegen::WorldInventory` associated
265+
/// type to wire this [`Step`] with.
266+
fn step_type(&self) -> syn::Ident {
267+
format_ident!("{}", to_pascal_case(self.attr_name))
245268
}
246269

247270
/// Returns [`syn::Ident`] and parsing code of the given function's

codegen/src/derive.rs

+47-88
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use proc_macro2::TokenStream;
1515
use quote::{format_ident, quote};
1616

1717
/// Generates code of `#[derive(WorldInit)]` macro expansion.
18+
#[allow(clippy::similar_names)]
1819
pub(crate) fn world_init(
1920
input: TokenStream,
2021
steps: &[&str],
@@ -26,10 +27,16 @@ pub(crate) fn world_init(
2627
let step_types = step_types(steps, world);
2728
let step_structs = generate_step_structs(steps, &input);
2829

30+
let given_ty = &step_types[0];
31+
let when_ty = &step_types[1];
32+
let then_ty = &step_types[2];
33+
2934
Ok(quote! {
30-
impl ::cucumber::codegen::WorldInventory<
31-
#( #step_types, )*
32-
> for #world {}
35+
impl ::cucumber::codegen::WorldInventory for #world {
36+
type Given = #given_ty;
37+
type When = #when_ty;
38+
type Then = #then_ty;
39+
}
3340

3441
#( #step_structs )*
3542
})
@@ -41,10 +48,7 @@ pub(crate) fn world_init(
4148
fn step_types(steps: &[&str], world: &syn::Ident) -> Vec<syn::Ident> {
4249
steps
4350
.iter()
44-
.map(|step| {
45-
let step = to_pascal_case(step);
46-
format_ident!("Cucumber{}{}", step, world)
47-
})
51+
.map(|step| format_ident!("Cucumber{}{}", to_pascal_case(step), world))
4852
.collect()
4953
}
5054

@@ -53,7 +57,8 @@ fn generate_step_structs(
5357
steps: &[&str],
5458
world: &syn::DeriveInput,
5559
) -> Vec<TokenStream> {
56-
let (world, world_vis) = (&world.ident, &world.vis);
60+
let world_vis = &world.vis;
61+
let world = &world.ident;
5762

5863
step_types(steps, world)
5964
.iter()
@@ -63,35 +68,23 @@ fn generate_step_structs(
6368
#[doc(hidden)]
6469
#world_vis struct #ty {
6570
#[doc(hidden)]
66-
pub loc: ::cucumber::step::Location,
71+
#world_vis loc: ::cucumber::step::Location,
6772

6873
#[doc(hidden)]
69-
pub regex: ::cucumber::codegen::Regex,
74+
#world_vis regex: ::cucumber::codegen::LazyRegex,
7075

7176
#[doc(hidden)]
72-
pub func: ::cucumber::Step<#world>,
77+
#world_vis func: ::cucumber::Step<#world>,
7378
}
7479

7580
#[automatically_derived]
7681
impl ::cucumber::codegen::StepConstructor<#world> for #ty {
77-
fn new (
78-
loc: ::cucumber::step::Location,
79-
regex: ::cucumber::codegen::Regex,
80-
func: ::cucumber::Step<#world>,
81-
) -> Self {
82-
Self { loc, regex, func }
83-
}
84-
8582
fn inner(&self) -> (
8683
::cucumber::step::Location,
87-
::cucumber::codegen::Regex,
84+
::cucumber::codegen::LazyRegex,
8885
::cucumber::Step<#world>,
8986
) {
90-
(
91-
self.loc.clone(),
92-
self.regex.clone(),
93-
self.func.clone(),
94-
)
87+
(self.loc, self.regex, self.func)
9588
}
9689
}
9790

@@ -114,45 +107,35 @@ mod spec {
114107
};
115108

116109
let output = quote! {
117-
impl ::cucumber::codegen::WorldInventory<
118-
CucumberGivenWorld, CucumberWhenWorld, CucumberThenWorld,
119-
> for World {}
110+
impl ::cucumber::codegen::WorldInventory for World {
111+
type Given = CucumberGivenWorld;
112+
type When = CucumberWhenWorld;
113+
type Then = CucumberThenWorld;
114+
}
120115

121116
#[automatically_derived]
122117
#[doc(hidden)]
123118
pub struct CucumberGivenWorld {
124-
#[doc(hidden)]
125-
pub loc: ::cucumber::step::Location,
119+
#[doc(hidden)]
120+
pub loc: ::cucumber::step::Location,
126121

127-
#[doc(hidden)]
128-
pub regex: ::cucumber::codegen::Regex,
122+
#[doc(hidden)]
123+
pub regex: ::cucumber::codegen::LazyRegex,
129124

130-
#[doc(hidden)]
131-
pub func: ::cucumber::Step<World>,
125+
#[doc(hidden)]
126+
pub func: ::cucumber::Step<World>,
132127
}
133128

134129
#[automatically_derived]
135130
impl ::cucumber::codegen::StepConstructor<World> for
136131
CucumberGivenWorld
137132
{
138-
fn new (
139-
loc: ::cucumber::step::Location,
140-
regex: ::cucumber::codegen::Regex,
141-
func: ::cucumber::Step<World>,
142-
) -> Self {
143-
Self { loc, regex, func }
144-
}
145-
146133
fn inner(&self) -> (
147134
::cucumber::step::Location,
148-
::cucumber::codegen::Regex,
135+
::cucumber::codegen::LazyRegex,
149136
::cucumber::Step<World>,
150137
) {
151-
(
152-
self.loc.clone(),
153-
self.regex.clone(),
154-
self.func.clone(),
155-
)
138+
(self.loc, self.regex, self.func)
156139
}
157140
}
158141

@@ -162,38 +145,26 @@ mod spec {
162145
#[automatically_derived]
163146
#[doc(hidden)]
164147
pub struct CucumberWhenWorld {
165-
#[doc(hidden)]
166-
pub loc: ::cucumber::step::Location,
148+
#[doc(hidden)]
149+
pub loc: ::cucumber::step::Location,
167150

168-
#[doc(hidden)]
169-
pub regex: ::cucumber::codegen::Regex,
151+
#[doc(hidden)]
152+
pub regex: ::cucumber::codegen::LazyRegex,
170153

171-
#[doc(hidden)]
172-
pub func: ::cucumber::Step<World>,
154+
#[doc(hidden)]
155+
pub func: ::cucumber::Step<World>,
173156
}
174157

175158
#[automatically_derived]
176159
impl ::cucumber::codegen::StepConstructor<World> for
177160
CucumberWhenWorld
178161
{
179-
fn new (
180-
loc: ::cucumber::step::Location,
181-
regex: ::cucumber::codegen::Regex,
182-
func: ::cucumber::Step<World>,
183-
) -> Self {
184-
Self { loc, regex, func }
185-
}
186-
187162
fn inner(&self) -> (
188163
::cucumber::step::Location,
189-
::cucumber::codegen::Regex,
164+
::cucumber::codegen::LazyRegex,
190165
::cucumber::Step<World>,
191166
) {
192-
(
193-
self.loc.clone(),
194-
self.regex.clone(),
195-
self.func.clone(),
196-
)
167+
(self.loc, self.regex, self.func)
197168
}
198169
}
199170

@@ -203,38 +174,26 @@ mod spec {
203174
#[automatically_derived]
204175
#[doc(hidden)]
205176
pub struct CucumberThenWorld {
206-
#[doc(hidden)]
207-
pub loc: ::cucumber::step::Location,
177+
#[doc(hidden)]
178+
pub loc: ::cucumber::step::Location,
208179

209-
#[doc(hidden)]
210-
pub regex: ::cucumber::codegen::Regex,
180+
#[doc(hidden)]
181+
pub regex: ::cucumber::codegen::LazyRegex,
211182

212-
#[doc(hidden)]
213-
pub func: ::cucumber::Step<World>,
183+
#[doc(hidden)]
184+
pub func: ::cucumber::Step<World>,
214185
}
215186

216187
#[automatically_derived]
217188
impl ::cucumber::codegen::StepConstructor<World> for
218189
CucumberThenWorld
219190
{
220-
fn new (
221-
loc: ::cucumber::step::Location,
222-
regex: ::cucumber::codegen::Regex,
223-
func: ::cucumber::Step<World>,
224-
) -> Self {
225-
Self { loc, regex, func }
226-
}
227-
228191
fn inner(&self) -> (
229192
::cucumber::step::Location,
230-
::cucumber::codegen::Regex,
193+
::cucumber::codegen::LazyRegex,
231194
::cucumber::Step<World>,
232195
) {
233-
(
234-
self.loc.clone(),
235-
self.regex.clone(),
236-
self.func.clone(),
237-
)
196+
(self.loc, self.regex, self.func)
238197
}
239198
}
240199

src/cli.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ and may be extended with custom CLI options additionally.
6464
# }
6565
# }
6666
#
67-
# let fut = async {
67+
# #[tokio::main(flavor = "current_thread")]
68+
# async fn main() {
6869
#[derive(StructOpt)]
6970
struct CustomOpts {
7071
/// Additional time to wait in before hook.
@@ -83,13 +84,7 @@ MyWorld::cucumber()
8384
.with_cli(opts)
8485
.run_and_exit("tests/features/readme")
8586
.await;
86-
# };
87-
#
88-
# tokio::runtime::Builder::new_current_thread()
89-
# .enable_all()
90-
# .build()
91-
# .unwrap()
92-
# .block_on(fut);
87+
# }
9388
```
9489
9590
[`Cucumber`]: crate::Cucumber

0 commit comments

Comments
 (0)