You could do this:
# frozen_string_literal: true
require 'dry/validation'
require 'date'
module Types
include Dry::Types()
MyDate = Types::Date.constructor do |value|
::Date.today + 1 if value.eql?('1 day')
end
end
class MyContract < Dry::Validation::Contract
params do
required(:duration).filter(:string, :filled?).value(Types::MyDate)
end
end
contract = MyContract.new
puts contract.(duration: nil).inspect
#<Dry::Validation::Result{:duration=>nil} errors={:duration=>["must be a string"]}>
puts contract.(duration: "").inspect
#<Dry::Validation::Result{:duration=>""} errors={:duration=>["must be filled"]}>
puts contract.(duration: "foo bar").inspect
#<Dry::Validation::Result{:duration=>nil} errors={:duration=>["must be a date"]}>
puts contract.(duration: "1 day").inspect
#<Dry::Validation::Result{:duration=>#<Date: 2019-07-31 ((2458696j,0s,0n),+0s,2299161j)>} errors={}>
You can read more about filter rules here.