Skip to content

Commit 9cb8206

Browse files
authored
Cucumber Expressions AST into Regex expansion (#2)
1 parent b71500c commit 9cb8206

File tree

9 files changed

+1017
-18
lines changed

9 files changed

+1017
-18
lines changed

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,39 @@ jobs:
5353
# Testing #
5454
###########
5555

56+
feature:
57+
name: Feature
58+
if: ${{ github.ref == 'refs/heads/main'
59+
|| startsWith(github.ref, 'refs/tags/v')
60+
|| !contains(github.event.head_commit.message, '[skip ci]') }}
61+
strategy:
62+
fail-fast: false
63+
matrix:
64+
feature:
65+
- <none>
66+
- into-regex
67+
runs-on: ubuntu-latest
68+
steps:
69+
- uses: actions/checkout@v2
70+
- uses: actions-rs/toolchain@v1
71+
with:
72+
profile: minimal
73+
toolchain: nightly
74+
- uses: actions-rs/toolchain@v1
75+
with:
76+
profile: minimal
77+
toolchain: stable
78+
override: true
79+
80+
- run: cargo +nightly update -Z minimal-versions
81+
82+
- run: cargo check --no-default-features
83+
${{ matrix.feature != '<none>'
84+
&& format('--features {0}', matrix.feature)
85+
|| '' }}
86+
env:
87+
RUSTFLAGS: -D warnings
88+
5689
msrv:
5790
name: MSRV
5891
if: ${{ github.ref == 'refs/heads/main'
@@ -141,6 +174,7 @@ jobs:
141174
name: Release on GitHub
142175
needs:
143176
- clippy
177+
- feature
144178
- msrv
145179
- rustdoc
146180
- rustfmt

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ All user visible changes to `cucumber-expressions` crate will be documented in t
1212
### Added
1313

1414
- [Cucumber Expressions] AST and parser. ([#1])
15+
- Expansion of [Cucumber Expressions] AST into [`Regex`] behind `into-regex` feature flag. ([#2])
1516

1617
[#1]: /../../pull/1
18+
[#2]: /../../pull/2
1719

1820

1921

2022

23+
[`Regex`]: https://docs.rs/regex
24+
2125
[Cucumber Expressions]: https://github.com/cucumber/cucumber-expressions#readme
2226
[Semantic Versioning 2.0.0]: https://semver.org

Cargo.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,22 @@ categories = ["compilers", "parser-implementations"]
1717
keywords = ["cucumber", "expression", "expressions", "cucumber-expressions"]
1818
include = ["/src/", "/LICENSE-*", "/README.md", "/CHANGELOG.md"]
1919

20+
[package.metadata.docs.rs]
21+
all-features = true
22+
rustdoc-args = ["--cfg", "docsrs"]
23+
24+
[features]
25+
# Enables ability to expand AST into regex.
26+
into-regex = ["either", "regex"]
27+
2028
[dependencies]
21-
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error"], default_features = false }
29+
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error", "from", "into"], default_features = false }
2230
nom = "7.0"
2331
nom_locate = "4.0"
2432

33+
# "into-regex" feature dependencies
34+
either = { version = "1.6", optional = true }
35+
regex = { version = "1.5", optional = true }
36+
2537
# TODO: Remove once `derive_more` 0.99.17 is released.
2638
syn = "1.0.81"

README.md

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,32 @@
22
===============================
33

44
[![Documentation](https://docs.rs/cucumber-expressions/badge.svg)](https://docs.rs/cucumber-expressions)
5-
[![CI](https://github.com/cucumber-rs/cucumber-expressions/workflows/CI/badge.svg?branch=master "CI")](https://github.com/cucumber-rs/cucumber-expressions/actions?query=workflow%3ACI+branch%3Amaster)
5+
[![CI](https://github.com/cucumber-rs/cucumber-expressions/workflows/CI/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber-expressions/actions?query=workflow%3ACI+branch%3Amaster)
66
[![Rust 1.56+](https://img.shields.io/badge/rustc-1.56+-lightgray.svg "Rust 1.56+")](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
77
[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)
88

99
- [Changelog](https://github.com/cucumber-rs/cucumber-expressions/blob/main/CHANGELOG.md)
1010

1111
Rust implementation of [Cucumber Expressions].
1212

13-
This crate provides [AST] and parser of [Cucumber Expressions].
13+
This crate provides [AST] parser, and [`Regex`] expansion of [Cucumber Expressions].
14+
15+
```rust
16+
use cucumber_expressions::Expression;
17+
18+
let re = Expression::regex("I have {int} cucumbers in my belly").unwrap();
19+
let caps = re.captures("I have 42 cucumbers in my belly").unwrap();
20+
21+
assert_eq!(&caps[0], "I have 42 cucumbers in my belly");
22+
assert_eq!(&caps[1], "42");
23+
```
24+
25+
26+
27+
28+
## Cargo features
29+
30+
- `into-regex`: Enables expansion into [`Regex`].
1431

1532

1633

@@ -27,7 +44,7 @@ single-expression = alternation
2744
| optional
2845
| parameter
2946
| text-without-whitespace+
30-
| whitespace
47+
| whitespace+
3148
text-without-whitespace = (- (text-to-escape | whitespace))
3249
| ('\', text-to-escape)
3350
text-to-escape = '(' | '{' | '/' | '\'
@@ -37,7 +54,8 @@ single-alternation = ((text-in-alternative+, optional*)
3754
| (optional+, text-in-alternative+))+
3855
text-in-alternative = (- alternative-to-escape)
3956
| ('\', alternative-to-escape)
40-
alternative-to-escape = ' ' | '(' | '{' | '/' | '\'
57+
alternative-to-escape = whitespace | '(' | '{' | '/' | '\'
58+
whitespace = ' '
4159
4260
optional = '(' text-in-optional+ ')'
4361
text-in-optional = (- optional-to-escape) | ('\', optional-to-escape)
@@ -51,6 +69,13 @@ name-to-escape = '{' | '}' | '(' | '/' | '\'
5169

5270

5371

72+
## [`Regex`] Production Rules
73+
74+
Follows original [production rules].
75+
76+
77+
78+
5479
## License
5580

5681
This project is licensed under either of
@@ -63,8 +88,11 @@ at your option.
6388

6489

6590

91+
[`Regex`]: https://docs.rs/regex
92+
6693
[AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
6794
[Cucumber Expressions]: https://github.com/cucumber/cucumber-expressions#readme
6895
[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus–Naur_form
6996

7097
[1]: https://github.com/cucumber/cucumber-expressions/issues/41
98+
[2]: https://github.com/cucumber/cucumber-expressions/blob/main/ARCHITECTURE.md#production-rules

src/ast.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,14 @@ pub enum SingleExpression<Input> {
8686
/// [0]: crate#grammar
8787
Parameter(Parameter<Input>),
8888

89-
/// Text without whitespaces.
89+
/// [`text-without-whitespace+`][0] expression.
90+
///
91+
/// [0]: crate#grammar
9092
Text(Input),
9193

92-
/// Whitespaces are treated as a special case to avoid placing every `text`
93-
/// character in a separate [AST] node, as described in the
94-
/// [grammar spec][0].
94+
/// [`whitespace+`][0] expression.
9595
///
9696
/// [0]: crate#grammar
97-
/// [AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
9897
Whitespaces(Input),
9998
}
10099

0 commit comments

Comments
 (0)