module Validator

Overview

∠(・.-)―〉 →◎ validator is a Crystal data validation module. Very simple and efficient, all validations return true or false.

Also validator/check (not exposed by default) provides error message handling intended for the end user.

There are 2 main ways to use validator:

By default the validator module expose only Validator and Valid (alias) in the scope:

require "validator"

Valid.email? "[email protected]"                        # => true
Valid.url? "https://github.com/Nicolab/crystal-validator" # => true
Valid.my_validator? "value to validate", "hello", 42      # => true

An (optional) expressive validation flavor, is available as an alternative.
Not exposed by default, it must be imported:

require "validator/is"

is :email?, "[email protected]"                        # => true
is :url?, "https://github.com/Nicolab/crystal-validator" # => true
is :my_validator?, "value to validate", "hello", 42      # => true

# raises an error if the email is not valid
is! :email?, "contact@@example..org" # => Validator::Error

is is a macro, no overhead during the runtime 🚀 By the nature of the macros, you can't pass the validator name dynamically with a variable like that is(validator_name, "my value to validate", arg). But of course you can pass arguments with variables is(:validator_name?, arg1, arg2).

Check

Make a series of checks, with a customized error message for each case.

require "validator/check"

check = Check.new

check("email", "The email is required.", is :absence?, "email", user)

Custom validator

Just add your own method to register a custom validator or to overload an existing validator.

module Validator
  # My custom validator
  def self.my_validator?(value, arg : String, another_arg : Int32) : Bool
    # write here the logic of your validator...
    return true
  end
end

# Call it
puts Valid.my_validator?("value to validate", "hello", 42) # => true

# or with the `is` flavor
puts is :my_validator?, "value to validate", "hello", 42 # => true

Check is a simple and lightweight wrapper, let your imagination run wild to add your logic around it.

Using the custom validator with the validation rules:

require "validator/check"

class Article
  # Mixin
  Check.checkable

  property title : String
  property content : String

  Check.rules(
    content: {
      # Now the custom validator is available
      check: {
        my_validator: {"My validator error message"},
        between:      {"The article content must be between 10 and 20 000 characters", 10, 20_000},
        # ...
      },
    },
  )
end

# Triggered with all data
v, article = Article.check(input_data)

# Triggered with one value
v, content = Article.check_content(input_data["content"]?)

Defined in:

lib/validator/src/validator.cr
lib/validator/src/validators/alpha_num.cr
lib/validator/src/validators/case_sensitive.cr
lib/validator/src/validators/comparisons.cr
lib/validator/src/validators/format.cr
lib/validator/src/validators/geo.cr
lib/validator/src/validators/presence.cr
lib/validator/src/validators/uri.cr
dynfork.cr

Class Method Summary

Class Method Detail

def self.color_code?(value : String) : Bool #

Custom validator to validate the color code string.

NOTE Examples: #fff | #f2f2f2 | #f2f2f200 | rgb(255,0,24) | rgba(255,0,24,0.5) | rgba(#fff,0.5) | hsl(120,100%,50%) | hsla(170,23%,25%,0.2) | 0x00ffff


[View source]
def self.password?(value : String) : Bool #

Custom validator to validate the password string.


[View source]
def self.phone_number?(value : String) : Bool #

Custom validator to validate the phone number string.


[View source]