{"id":20527620,"url":"https://github.com/cucumber-rs/cucumber-expressions","last_synced_at":"2025-04-09T21:23:21.499Z","repository":{"id":43420798,"uuid":"425036332","full_name":"cucumber-rs/cucumber-expressions","owner":"cucumber-rs","description":"Rust implementation of Cucumber Expressions.","archived":false,"fork":false,"pushed_at":"2025-02-21T22:43:10.000Z","size":124,"stargazers_count":11,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T20:08:05.560Z","etag":null,"topics":["cucumber","cucumber-expressions","cucumber-rust","rust"],"latest_commit_sha":null,"homepage":"https://cucumber.github.io/cucumber-expressions","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cucumber-rs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-05T17:44:56.000Z","updated_at":"2025-02-21T22:43:14.000Z","dependencies_parsed_at":"2023-11-16T21:03:01.309Z","dependency_job_id":"66a82d5c-1f69-469e-8fea-f4cc34f7de88","html_url":"https://github.com/cucumber-rs/cucumber-expressions","commit_stats":{"total_commits":43,"total_committers":3,"mean_commits":"14.333333333333334","dds":"0.16279069767441856","last_synced_commit":"4546670119a89425dbabfd173969ab8f821b1108"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber-rs%2Fcucumber-expressions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber-rs%2Fcucumber-expressions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber-rs%2Fcucumber-expressions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber-rs%2Fcucumber-expressions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cucumber-rs","download_url":"https://codeload.github.com/cucumber-rs/cucumber-expressions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248113098,"owners_count":21049783,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cucumber","cucumber-expressions","cucumber-rust","rust"],"created_at":"2024-11-15T23:19:32.421Z","updated_at":"2025-04-09T21:23:21.477Z","avatar_url":"https://github.com/cucumber-rs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[Cucumber Expressions] for Rust\n===============================\n\n[![crates.io](https://img.shields.io/crates/v/cucumber-expressions.svg?maxAge=2592000 \"crates.io\")](https://crates.io/crates/cucumber-expressions)\n[![Rust 1.85+](https://img.shields.io/badge/rustc-1.85+-lightgray.svg \"Rust 1.85+\")](https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html)\n[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg \"Unsafe forbidden\")](https://github.com/rust-secure-code/safety-dance)  \n[![CI](https://github.com/cucumber-rs/cucumber-expressions/actions/workflows/ci.yml/badge.svg?branch=main \"CI\")](https://github.com/cucumber-rs/cucumber-expressions/actions?query=workflow%3ACI+branch%3Amain)\n[![Rust docs](https://docs.rs/cucumber-expressions/badge.svg \"Rust docs\")](https://docs.rs/cucumber-expressions)\n\n- [Changelog](https://github.com/cucumber-rs/cucumber-expressions/blob/v0.4.0/CHANGELOG.md)\n\nRust implementation of [Cucumber Expressions].\n\nThis crate provides [AST] parser, and [`Regex`] expansion of [Cucumber Expressions].\n\n```rust\n# // `Regex` expansion requires `into-regex` feature.\n# #[cfg(feature = \"into-regex\")] {\nuse cucumber_expressions::Expression;\n\nlet re = Expression::regex(\"I have {int} cucumbers in my belly\").unwrap();\nlet caps = re.captures(\"I have 42 cucumbers in my belly\").unwrap();\n\nassert_eq!(\u0026caps[0], \"I have 42 cucumbers in my belly\");\nassert_eq!(\u0026caps[1], \"42\");\n# }\n```\n\n\n\n\n## Cargo features\n\n- `into-regex`: Enables expansion into [`Regex`].\n\n\n\n\n## Grammar\n\nThis implementation follows a context-free grammar, [which isn't yet merged][1]. 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! \n\n[EBNF] spec of the current context-free grammar implemented by this crate:\n```ebnf\nexpression              = single-expression*\n\nsingle-expression       = alternation\n                           | optional\n                           | parameter\n                           | text-without-whitespace+\n                           | whitespace+\ntext-without-whitespace = (- (text-to-escape | whitespace))\n                           | ('\\', text-to-escape)\ntext-to-escape          = '(' | '{' | '/' | '\\'\n\nalternation             = single-alternation, (`/`, single-alternation)+\nsingle-alternation      = ((text-in-alternative+, optional*)\n                            | (optional+, text-in-alternative+))+\ntext-in-alternative     = (- alternative-to-escape)\n                           | ('\\', alternative-to-escape)\nalternative-to-escape   = whitespace | '(' | '{' | '/' | '\\'\nwhitespace              = ' '\n\noptional                = '(' text-in-optional+ ')'\ntext-in-optional        = (- optional-to-escape) | ('\\', optional-to-escape)\noptional-to-escape      = '(' | ')' | '{' | '/' | '\\'\n\nparameter               = '{', name*, '}'\nname                    = (- name-to-escape) | ('\\', name-to-escape)\nname-to-escape          = '{' | '}' | '(' | '/' | '\\'\n```\n\n\n\n\n## [`Regex`] Production Rules\n\nFollows original [production rules][2].\n\n\n\n\n## License\n\nThis project is licensed under either of\n\n* Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber-expressions/blob/v0.4.0/LICENSE-APACHE) or \u003chttp://www.apache.org/licenses/LICENSE-2.0\u003e)\n* MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber-expressions/blob/v0.4.0/LICENSE-MIT) or \u003chttp://opensource.org/licenses/MIT\u003e)\n\nat your option.\n\n\n\n\n[`Regex`]: https://docs.rs/regex\n\n[AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree\n[Cucumber Expressions]: https://github.com/cucumber/cucumber-expressions#readme\n[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus–Naur_form\n\n[1]: https://github.com/cucumber/cucumber-expressions/issues/41\n[2]: https://github.com/cucumber/cucumber-expressions/blob/main/ARCHITECTURE.md#production-rules\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcucumber-rs%2Fcucumber-expressions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcucumber-rs%2Fcucumber-expressions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcucumber-rs%2Fcucumber-expressions/lists"}