How to define conditional rules

I would like to “run” a rule only when the attribute/key is truthy, so something like:

class Search < Dry::Validation::Contract
  params do
    optional(:email).value(:string)
  end

  rule(:email) do
    key? && SomeLogicForValidation(value)
  end
end

Here I would like to get rid of “key?” somehow.
When I try with early return like return unless key? I’m getting an error: LocalJumpError.

Is it already possible somehow?

There’s an open issue with a potential new API for this, but for now you will have to rely on guard clauses.

The LocalJumpError happened because Procs don’t trap return, and the code is not running inside a method. Inside a proc you may use next to achieve the same result:

next unless key?

The difference between Proc and Lambda can be confusing but they each serve a different purpose, and work slightly differently because of that.

FWIW I usually write this kind of rule as

rule :email do
  SomeLogicForValidation(value) if key?
end

which honestly doesn’t seem that bad

Thank you. next works fine.
I added a bit simplified example. In my case the validation is few lines of codes, so the early return makes it much nicer.

Proposition with adding a guard to DSL looks nice.