6 releases

Uses new Rust 2021

0.2.1 Mar 9, 2022
0.2.0 Feb 10, 2022
0.1.2 Jan 11, 2022
0.1.1 Nov 29, 2021
0.0.0 Nov 5, 2021

#173 in Parser implementations

Download history 8425/week @ 2022-10-06 6194/week @ 2022-10-13 8931/week @ 2022-10-20 8180/week @ 2022-10-27 8644/week @ 2022-11-03 7669/week @ 2022-11-10 8312/week @ 2022-11-17 7239/week @ 2022-11-24 9395/week @ 2022-12-01 8517/week @ 2022-12-08 8568/week @ 2022-12-15 5807/week @ 2022-12-22 5379/week @ 2022-12-29 7385/week @ 2023-01-05 7752/week @ 2023-01-12 9517/week @ 2023-01-19

30,700 downloads per month
Used in 3 crates (2 directly)

MIT/Apache

150KB
3K SLoC

Cucumber Expressions for Rust

Documentation CI Rust 1.56+ Unsafe Forbidden

Rust implementation of Cucumber Expressions.

This crate provides AST parser, and Regex expansion of Cucumber Expressions.

use cucumber_expressions::Expression;

let re = Expression::regex("I have {int} cucumbers in my belly").unwrap();
let caps = re.captures("I have 42 cucumbers in my belly").unwrap();

assert_eq!(&caps[0], "I have 42 cucumbers in my belly");
assert_eq!(&caps[1], "42");

Cargo features

  • into-regex: Enables expansion into Regex.

Grammar

This implementation follows a context-free grammar, which isn't yet merged. Original grammar is impossible to follow while creating a performant parser, as it consists errors and describes not an exact Cucumber Expressions language, but rather some superset language, while being also context-sensitive. In case you've found some inconsistencies between this implementation and the ones in other languages, please file an issue!

EBNF spec of the current context-free grammar implemented by this crate:

expression              = single-expression*

single-expression       = alternation
                           | optional
                           | parameter
                           | text-without-whitespace+
                           | whitespace+
text-without-whitespace = (- (text-to-escape | whitespace))
                           | ('\', text-to-escape)
text-to-escape          = '(' | '{' | '/' | '\'

alternation             = single-alternation, (`/`, single-alternation)+
single-alternation      = ((text-in-alternative+, optional*)
                            | (optional+, text-in-alternative+))+
text-in-alternative     = (- alternative-to-escape)
                           | ('\', alternative-to-escape)
alternative-to-escape   = whitespace | '(' | '{' | '/' | '\'
whitespace              = ' '

optional                = '(' text-in-optional+ ')'
text-in-optional        = (- optional-to-escape) | ('\', optional-to-escape)
optional-to-escape      = '(' | ')' | '{' | '/' | '\'

parameter               = '{', name*, '}'
name                    = (- name-to-escape) | ('\', name-to-escape)
name-to-escape          = '{' | '}' | '(' | '/' | '\'

Regex Production Rules

Follows original production rules.

License

This project is licensed under either of

at your option.

Dependencies

~1–1.9MB
~42K SLoC