I just realized this works:
require "dry/schema"
inner_schema = Dry::Schema.Params do
required(:path).filled(:string)
end
outer_schema = Dry::Schema.Params do
required(:foo).maybe(:hash, inner_schema)
end
puts outer_schema.(foo: { path: "something" }).inspect
#<Dry::Schema::Result{:foo=>{:path=>"something"}} errors={}>
puts outer_schema.(foo: { path: "" }).inspect
#<Dry::Schema::Result{:foo=>{:path=>""}} errors={:foo=>{:path=>["must be filled"]}}>
puts outer_schema.(foo: "").inspect
#<Dry::Schema::Result{:foo=>nil} errors={}>
puts outer_schema.(foo: nil).inspect
#<Dry::Schema::Result{:foo=>nil} errors={}>
This is because a hash?
check is applied separately from applying your schema. I can see how that’s confusing though - using an inner schema should probably imply a hash?
check too