ValidatorFn
ValidatorFn is a collection of very simple lambdas that can be used for validating/transforming data structures. It makes use of currying to provide a very composable DSL. To help you understand the concepts, I strongly advise reading this blog post..
It can be very useful for validating structures that come from input, such as configuration files, JSON APIs, test results.
Installation
Add this line to your application's Gemfile:
gem 'validator_fn'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install validator_fn
Usage
require 'validator_fn'
include ValidatorFn
You can start validating the type of an object.
is_a.(String).(3)
Note that parameters are curried. The first param of is_a
is the Ruby class you want to check the last parameter against.
In the previous example, a ValidatorFn::Error
exception will be raised.
However, setting a valid entry as the second parameter will return that last parameter.
is_a.(String).("Joe")
# => "Joe"
This allows chaining lambdas:
to_int = is_a.(String) >> -> a { Integer(a) }
to_int.("12")
# => 12
to_int.("asdf") # will raise an exception
You can validate a hash:
user = hash_of.({name: is_a.(String), age: to_int})
user.({name: "", age: "234"})
Since we are using curried lambdas, you can compose validators as you wish.
postal_code = -> a {
invalid.("Invalid postal code: #{a}") unless a =~ /[a-z]\d[a-z]\s*\d[a-z]\d/i
a
}
contact = hash_of.(user: user,
address: hash_of.({ street_number: is_a.(Integer),
postal_code: postal_code}))
This very simple library (100 lines of code) can be extended easily by creating new lambdas.
Casting
You can also apply converter functions to the structure.
user = { name: "Joe", created_at: "2020-01-03" }
to_date = ->str { Date.parse(str) }
user_validator = hash_of.(name: is_a.(String),
created_at: is_a.(String) >> to_date)
user_validator.(user)
# => {:name=>"Joe", :created_at=>#<Date: 2020-01-03 ((2458852j,0s,0n),+0s,2299161j)>}
This makes it very useful for processing JSON payloads.
Code generation
You can generate validator code from existing structure:
require 'openuri'
require "json"
struct = JSON.parse(URI.open("https://api.github.com/users/defunkt").read)
require "validator_fn"
# Generate unformatted code
code = ValidatorFn.generate_validator.(struct)
# You can reformat it using a code formatter
require "rufo"
puts Rufo.format(code)
The output
hash_of.({ "login" => is_a.(String),
"id" => is_a.(Integer),
"node_id" => is_a.(String),
"avatar_url" => is_a.(String),
"gravatar_id" => is_a.(String),
"url" => is_a.(String),
"html_url" => is_a.(String),
"followers_url" => is_a.(String),
"following_url" => is_a.(String),
"gists_url" => is_a.(String),
"starred_url" => is_a.(String),
"subscriptions_url" => is_a.(String),
"organizations_url" => is_a.(String),
"repos_url" => is_a.(String),
"events_url" => is_a.(String),
"received_events_url" => is_a.(String),
"type" => is_a.(String),
"site_admin" => is_a_bool,
"name" => is_a.(String),
"company" => any,
"blog" => is_a.(String),
"location" => any,
"email" => any,
"hireable" => any,
"bio" => is_a.(String),
"twitter_username" => any,
"public_repos" => is_a.(Integer),
"public_gists" => is_a.(Integer),
"followers" => is_a.(Integer),
"following" => is_a.(Integer),
"created_at" => is_a.(String),
"updated_at" => is_a.(String) })
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/validator_fn. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the ValidatorFn project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.