lib/dry/validation/rule.rb in dry-validation-1.0.0.rc3 vs lib/dry/validation/rule.rb in dry-validation-1.0.0

- old
+ new

@@ -1,11 +1,11 @@ # frozen_string_literal: true require 'dry/equalizer' -require 'dry/initializer' require 'dry/validation/constants' +require 'dry/validation/function' module Dry module Validation # Rules capture configuration and evaluator blocks # @@ -13,40 +13,38 @@ # block will be evaluated in the context of the evaluator. # # @see Contract#rule # # @api public - class Rule + class Rule < Function include Dry::Equalizer(:keys, :block, inspect: false) - extend Dry::Initializer - # @!attribute [r] keys # @return [Array<Symbol, String, Hash>] # @api private option :keys # @!attribute [r] macros # @return [Array<Symbol>] # @api private option :macros, default: proc { EMPTY_ARRAY.dup } - # @!attribute [r] block - # @return [Proc] - # @api private - option :block - # Evaluate the rule within the provided context # # @param [Contract] contract # @param [Result] result # # @api private def call(contract, result) Evaluator.new( contract, - values: result.values, keys: keys, macros: macros, _context: result.context, + keys: keys, + macros: macros, + block_options: block_options, + result: result, + values: result.values, + _context: result.context, &block ) end # Define which macros should be executed @@ -54,11 +52,43 @@ # @see Contract#rule # @return [Rule] # # @api public def validate(*macros, &block) - @macros = macros + @macros = macros.map { |spec| Array(spec) }.map(&:flatten) @block = block if block + self + end + + # Define a validation function for each element of an array + # + # The function will be applied only if schema checks passed + # for a given array item. + # + # @example + # rule(:nums).each do + # key.failure("must be greater than 0") if value < 0 + # end + # + # @return [Rule] + # + # @api public + def each(*macros, &block) + root = keys + @keys = [] + + @block = proc do + values[root].each_with_index do |_, idx| + path = [*root, idx] + + next if result.error?(path) + + evaluator = with(macros: macros, keys: [path], &block) + + failures.concat(evaluator.failures) + end + end + self end # Return a nice string representation #