Skip to content

yeast: Support optional guards in rules - #22436

Draft
tausbn wants to merge 1 commit into
mainfrom
tausbn/yeast-support-optional-guards-in-rules
Draft

yeast: Support optional guards in rules#22436
tausbn wants to merge 1 commit into
mainfrom
tausbn/yeast-support-optional-guards-in-rules

Conversation

@tausbn

@tausbn tausbn commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Permits the use of guards of the form if expr (where expr is any Rust expression) inside of rules. The guard should come after the query itself, and before the => that separates the query from the body, like so:

(foo bar: _? @bar)
if !bar.is_none()
=> (baz bar: {bar})

If the guard is absent, it behaves as if it were if true. Inside of the guard body, all captures are treated as if they are raw. Translation of non-raw captures only happens if the guard succeeds.

The guard can also access the user-defined context. This context is shared with the body if the guard succeeds, and discarded if the guard fails (just as it is currently discarded after running a rule body). (I think it's unlikely that we'll ever want to mutate the context from inside the guard, but you never know...)

Permits the use of guards of the form `if expr` (where `expr` is any
Rust expression) inside of rules. The guard should come after the query
itself, and before the `=>` that separates the query from the body, like
so:

```
(foo bar: _? @bar)
if !bar.is_none()
=> (baz bar: {bar})
```

If the guard is absent, it behaves as if it were `if true`. Inside of
the guard body, all captures are treated as if they are raw. Translation
of non-raw captures only happens if the guard succeeds.

The guard can also access the user-defined context. This context is
shared with the body if the guard succeeds, and discarded if the guard
fails (just as it is currently discarded after running a rule body).
(I think it's unlikely that we'll ever want to mutate the context from
inside the guard, but you never know...)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds optional Rust-expression guards to Yeast rules, evaluated before capture translation.

Changes:

  • Adds runtime guard evaluation and context handling.
  • Extends macros with guard parsing and raw capture bindings.
  • Adds documentation and tests for guarded rules.
Show a summary per file
File Description
shared/yeast/src/lib.rs Adds guard runtime support.
shared/yeast-macros/src/parse.rs Parses and generates guarded rules.
shared/yeast-macros/src/lib.rs Documents macro guard syntax.
shared/yeast/doc/yeast.md Documents guard behavior.
shared/yeast/tests/test.rs Tests guards, captures, context, and macros.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread shared/yeast/src/lib.rs
/// Construct a rule from its query, guard, and transform. The guard sees
/// raw captures and shares its private user-context clone with the
/// transform when it succeeds.
pub fn new(query: QueryNode, guard: Guard<C>, transform: Transform<C>) -> Self {
Comment thread shared/yeast/src/lib.rs
Comment on lines +1293 to +1294
let mut local = user_ctx.clone();
if let Some(captures) = rule.try_match(ast, id, &mut local)? {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants