Hv

Hash validation. At the moment the validation only return true or false when it match the schema.

Installation

Add this line to your application's Gemfile:

gem 'hv'

And then execute:

$ bundle

Or install it yourself as:

$ gem install hv

Usage

person_schema = { name: {type?: String} }
schema = {
    people: {
        array?: person_schema
    }
}
schema = Schema.new(schema)
schema.validates?({people: [{name: "juan"}, {name: "chus"}]}) # => true

Another example with custom validators and error processing


 module MyAwesomeErrorProcessor

    def self.call(result, i18n_errors_hash)
        result.map do |path, validator, spec, given|
        path_text = path.empty? ? "" : " in #{path}"
        i18n_errors_hash[validator] % {path: path_text, validator: validator, spec: spec, given: given.inspect}
        end
    end

end

module I18nErrors

    def self.translations
        keys = {
        type?: "Expected %{given} to be a %{spec}",
        accept_if_underage: "You must accept if you're under 18"
        }
        keys.default = "Expected %{given}%{path} to be %{validator}:%{spec}"
        keys
    end

end


signUpForm = Hv::Schema.new do

    # set_schema: set the schema structure.
    set_schema ({
        name: {type?: String},
        # Custom validator :email?
        email: {email?: true},
        age: {type?: Integer},
        accept_underage: {types?: [TrueClass, FalseClass]}
    })

    # set_error_processor: accepts is an object that respond to call(result, i18n), it could be a block
    set_error_processor MyAwesomeErrorProcessor

    # set_i18n_errors: accepts a hash with validators names as keys
    set_i18n_errors I18nErrors.translations

    # validator: define a new validator key
    validator :email? do |spec, value, path|
        is_email = validate_type?(String, value, path) &&
                    validate_format?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i, value, path)
        !(is_email ^ spec)
    end

    # validate: define a custom validation block. You must add_error() if validation doesn't match.
    validate :accept_if_underage do |input|
        if (!input[:accept_underage] && input[:age] < 18)
        add_error([:accept_underage], :accept_if_underage, true, input[:accept_underage])
        end
    end

end

signUpForm.validates?({name: "Jhon", email: "[email protected]", age: 15, accept_underage: false})
# => false
signUpForm.errors
# => ["You must accept if you're under 18"]

Check 'test' folder for more validators examples.

TODO

  • Improve documentation
  • return errors
  • sanitize input

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Hv project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.