Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tonytonyjan/sukima
Sukima is a lightweight data schema validation library for Ruby written in only ~100 lines of code. It provides a simple and flexible way to define constraints for data and validate it.
https://github.com/tonytonyjan/sukima
ruby schema validation
Last synced: about 1 month ago
JSON representation
Sukima is a lightweight data schema validation library for Ruby written in only ~100 lines of code. It provides a simple and flexible way to define constraints for data and validate it.
- Host: GitHub
- URL: https://github.com/tonytonyjan/sukima
- Owner: tonytonyjan
- Created: 2024-06-25T05:31:04.000Z (6 months ago)
- Default Branch: master
- Last Pushed: 2024-07-23T02:02:01.000Z (5 months ago)
- Last Synced: 2024-07-24T04:38:06.276Z (5 months ago)
- Topics: ruby, schema, validation
- Language: Ruby
- Homepage:
- Size: 9.77 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
Awesome Lists containing this project
README
= Sukima image:https://github.com/tonytonyjan/sukima/actions/workflows/test.yml/badge.svg[]
Sukima is a lightweight data schema validation library for Ruby written in only ~100 lines of code.
It provides a simple and flexible way to define constraints for data schema and validate it.== Usage
Constraints are defined by keyword arguments such as `:type`, `:nonnil`, `:format`.
[source,ruby]
----
sukima = Sukima.new **constraints
result = sukima.validate(data)
result.to_h # => Nested hash of validation results
result.message # => Array of error messages
----To see built-in constraints, check `lib/sukima/constraints.rb`.
== Quick Start
[source,ruby]
----
require 'sukima'sukima = Sukima.new type: Hash do
field :id, required: true
field :name, type: String, format: /\A[a-z]+\z/
field :age, type: Integer, in: 20..100
field :nicknames, type: Array, length: 3 do
items type: String, nonnil: true
end
endresult = sukima.validate( {name: 'JOHN', age: 18, nicknames: [1, nil] })
result.valid? # => false
result[:nicknames][1].messages # => ["should not be nil"]
result.messages
# =>
# ["id is required",
# "name should match \\A[a-z]+\\z",
# "age should be in 20..100",
# "nicknames should have length of 3",
# "nicknames.0 should be String",
# "nicknames.1 should not be nil"]
----== Custom Constraints
Any singleton method of `Sukima::Constraints` becomes a constraint.
A constraint method accepts two arguments, the first is the constraint configuration passed by the user and the second is the value to be validated.
It returnes a message if the value is invalid, otherwise `nil`.Below is how `lib/sukima/constraints.rb` implements the built-in constraint `:type`:
[source,ruby]
----
class Sukima::Constraints
def self.type(type, value)
"should be #{type}" unless value.is_a?(type)
end
end
----== Reusing Constraints
`#field` and `#items` can take an `Sukima` object as an argument:
[source,ruby]
----
shared = Sukima.new type: Integer, in: 1..10sukima = Sukima.new type: Hash do
field :score, shared
field :scores, type: Array do
items shared
end
end
sukima.validate({score: 0, scores: [11]}).messages
# => ["score should be in 1..10", "scores.0 should be in 1..10"]
----Reusing blocks is also possible:
[source,ruby]
----
shared = proc do
field :name, type: String
field :age, type: Integer
endsukima = Sukima.new type: Hash do
field :email, type: String
instance_eval(&shared)
endsukima.validate({ name: 1, age: '20', email: 1 }).messages
# => ["email should be String", "name should be String", "age should be Integer"]
----== Conditional Validation
`#field` and `#items` yields the value to the block so that you can define complex rules based on the value, this is useful for cases like polymorphic associations:
[source,ruby]
----
sukima = Sukima.new type: Array do
items type: Hash do |hash|
field :type, type: String, in: %w[website user]case hash[:type]
when 'website'
field :url, required: true
when 'user'
field :email, required: true
end
end
endsukima.validate(
[
{ type: 'website' },
{ type: 'user' }
]
).messages
# => ["0.url is required", "1.email is required"]
----