Custom Predicates

You can simply define predicate methods on your schema object:

schema = Dry::Validation.Schema do
  configure do
    def email?(value)
      ! /magical-regex-that-matches-emails/.match(value).nil?
    end
  end

  required(:email).filled(:str?, :email?)
end

You can also re-use a predicate container across multiple schemas:

module MyPredicates
  include Dry::Logic::Predicates

  predicate(:email?) do |value|
    ! /magical-regex-that-matches-emails/.match(value).nil?
  end
end

schema = Dry::Validation.Schema do
  configure do
    predicates(MyPredicates)
  end

  required(:email).filled(:str?, :email?)
end

You need to provide error messages for your custom predicates if you want them to work with Schema#call(input).messages interface.

You can learn how to do that in the Error Messages section.