module Formulario class Field class UnvalidatedField attr_accessor :field_name attr_accessor :value attr_accessor :field_type attr_accessor :default attr_accessor :validators attr_accessor :form def initialize( field_name: , value: nil, field_type: Field, default: Field.type_for(field_type).default, validators: [] ) @field_name = field_name @field_type = field_type @default = default @validators = validators end def validate(validator=Undefined, message: Undefined, &validation_block) validation_function = case when block_given? validation_block when validator.is_a?(Symbol) validator when validator.is_a?(::Formulario::Validator) validator end validators << { validator: validation_function, message: message, } end def validate!(form) self.form = form validators.inject(field_type.for(value.value)) do |current_value, validator_hash| validator_block = case validator_hash[:validator] when ::Formulario::Validator validator_hash[:validator] when Symbol ::Formulario::Validator.new(&value.method(validator_hash[:validator])) when Proc ::Formulario::Validator.new(&validator_hash[:validator]) end if instance_exec(value: value.value, object: self, field_name: field_name, &validator_block.to_proc).valid? current_value else message = if validator_hash[:validator].is_a?(::Formulario::Validator) validator_hash[:validator].message end value.exceptional_class .new(current_value, reasons: message || validator_hash[:message]) end end end end end end