lib/dry/validation/schema/value.rb in dry-validation-0.6.0 vs lib/dry/validation/schema/value.rb in dry-validation-0.7.0

- old
+ new

@@ -1,52 +1,102 @@ +require 'dry/validation/schema/dsl' + module Dry module Validation class Schema - class Value < BasicObject - include Schema::Definition + class Value < DSL + attr_reader :type, :schema_class - attr_reader :name, :rules, :groups, :checks + def initialize(options = {}) + super + @type = options.fetch(:type, :key) + @schema_class = options.fetch(:schema_class, ::Class.new(Schema)) + end - def initialize(name) - @name = name - @rules = [] - @groups = [] - @checks = [] + def configure(&block) + klass = ::Class.new(schema_class, &block) + @schema_class = klass + self end - def each(&block) - val_rule = yield(self) + def root? + name.nil? + end - each_rule = - if val_rule.is_a?(Schema::Rule) - val_rule.to_ary + def class + Value + end + + def each(*predicates, &block) + val = + if predicates.size > 0 + predicates + .reduce(Value.new) { |a, e| a.__send__(*::Kernel.Array(e)) } else - [:set, [name, rules.map(&:to_ary)]] + Value[name].instance_eval(&block) end - Schema::Rule.new(name, [:each, [name, each_rule]]) + rule = array?.and(create_rule([:each, val.to_ast])) + + add_rule(rule) if root? + + rule end + def when(*predicates, &block) + left = predicates + .reduce(Check[path, type: type]) { |a, e| a.__send__(*::Kernel.Array(e)) } + + right = Value.new(type: type) + right.instance_eval(&block) + + add_check(left.then(create_rule(right.to_ast))) + + self + end + + def rule(id = nil, **options, &block) + if id + val = Value[id] + res = val.instance_exec(&block) + else + id, deps = options.to_a.first + val = Value[id] + res = val.instance_exec(*deps.map { |name| val.value(name) }, &block) + end + + add_check(val.with(rules: [res.with(deps: deps || [])])) + end + + def confirmation + rule = check(:"#{name}_confirmation") + .eql?(check(name)) + .with(deps: [name]) + + add_check(rule) + end + + def value(name) + check(name, rules: rules) + end + + def check(name, options = {}) + Check[name, options.merge(type: type)] + end + private def method_missing(meth, *args, &block) - rule = Schema::Rule.new(name, [:val, [name, [:predicate, [meth, args]]]]) + val_rule = create_rule([:val, [:predicate, [meth, args]]]) if block - val_rule = yield + val = Value.new.instance_eval(&block) + new_rule = create_rule([:and, [val_rule.to_ast, val.to_ast]]) - if val_rule.is_a?(Schema::Rule) - rule & val_rule - else - Schema::Rule.new(name, [:and, [rule.to_ary, [:set, [name, rules.map(&:to_ary)]]]]) - end + add_rule(new_rule) else - rule + val_rule end - end - - def respond_to_missing?(meth, _include_private = false) - true end end end end end