-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch from virtus to dry-types #1347
Comments
Thanks for sharing this @guizmaii! I read the post with great interest. I would be open to a PR that replaces Virtus with something else, we can look at the implications. |
Happy to see this proposal. I was also wondering if maybe you could leverage |
Very good, if possible, I want to get involved @dblock |
Looking forward to pull requests @totothink. |
Looks like this enhancement requires a lot of refactoring. Grape tied on |
require 'dry/schema'
module Validation
class DSL
attr_reader :schema
OPTS_MAPPING = {
regexp: -> v { { format?: v } },
type: -> v { v.name.downcase.to_sym }
}
def initialize
@schema = Dry::Schema::DSL.new(processor_type: Dry::Schema::Params)
end
def call
schema.call
end
def requires(name, opts)
schema.required(name).value(*convert_opts(opts))
self
end
def optional(name, opts)
schema.optional(name).value(*convert_opts(opts))
self
end
private
def convert_opts(opts)
opts.each_with_object([]) do |(k, v), arr|
arg = OPTS_MAPPING.fetch(k).(v)
arr << arg
end
end
end
def params(&block)
@schema =
begin
dsl = DSL.new
dsl.instance_eval(&block)
dsl.call
end
end
def schema
@schema
end
end
class Grape
extend Validation
params do
requires :id, type: Integer
optional :text, type: String, regexp: /\A[a-z]+\z/
end
end
puts Grape.schema.(id: '1', text: '123').inspect
#<Dry::Schema::Result{:id=>1, :text=>"123"} errors={:text=>["is in invalid format"]}>
puts Grape.schema.(id: '1', text: 'foo').inspect
#<Dry::Schema::Result{:id=>1, :text=>"foo"} errors={}> 👋 so I just wrote this, as a quick PoC. This uses dry-types under the hood for coercion. |
as already mentioned above, if something will be refactored, it would be nice to see a solution with an ability to disable/replace validation component at all. I see |
You may be interested then in the fact dry-schema exposes the definition via AST which can be reused for any purpose you mentioned schema = Dry::Schema.Params do
required(:user).type(:hash).schema do
required(:email).type(:string)
required(:age).type(:integer)
required(:address).type(:hash).schema do
required(:street).type(:string)
required(:city).type(:string)
required(:zipcode).type(:string)
required(:location).type(:hash).schema do
required(:lat).type(:float)
required(:lng).type(:float)
end
end
end
end
schema.to_ast
=> [:set,
[[:and,
[[:predicate, [:key?, [[:name, :user], [:input, Undefined]]]],
[:key,
[:user,
[:and,
[[:predicate, [:hash?, [[:input, Undefined]]]],
[:set,
[[:predicate, [:key?, [[:name, :email], [:input, Undefined]]]],
[:predicate, [:key?, [[:name, :age], [:input, Undefined]]]],
[:and,
[[:predicate, [:key?, [[:name, :address], [:input, Undefined]]]],
[:key,
[:address,
[:and,
[[:predicate, [:hash?, [[:input, Undefined]]]],
[:set,
[[:predicate, [:key?, [[:name, :street], [:input, Undefined]]]],
[:predicate, [:key?, [[:name, :city], [:input, Undefined]]]],
[:predicate, [:key?, [[:name, :zipcode], [:input, Undefined]]]],
[:and,
[[:predicate, [:key?, [[:name, :location], [:input, Undefined]]]],
[:key,
[:location,
[:and,
[[:predicate, [:hash?, [[:input, Undefined]]]],
[:set, [[:predicate, [:key?, [[:name, :lat], [:input, Undefined]]]], [:predicate, [:key?, [[:name, :lng], [:input, Undefined]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] There's also another definition, with actual types |
Hello community, you are welcome to review my PR replacing virtus with dry-types. 🙂 Later we might bring dry-schema as well, but it will require more work and it will bring lots of breaking changes. So, let's start with dry-types 😉 |
I don't really know what you do with
virtus
(I think it's coercion) but I think it could be a good idea to replacevirtus
bydry-types
(http://dry-rb.org/gems/dry-types/) for many reasons:The text was updated successfully, but these errors were encountered: