dry-types 0.9.2 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +10 -6
- data/.yardopts +5 -0
- data/CHANGELOG.md +9 -1
- data/Gemfile +4 -1
- data/Rakefile +4 -0
- data/dry-types.gemspec +2 -1
- data/lib/dry/types.rb +25 -0
- data/lib/dry/types/array.rb +2 -0
- data/lib/dry/types/array/member.rb +16 -2
- data/lib/dry/types/builder.rb +17 -2
- data/lib/dry/types/coercions.rb +14 -2
- data/lib/dry/types/coercions/form.rb +18 -0
- data/lib/dry/types/coercions/json.rb +2 -0
- data/lib/dry/types/constrained.rb +21 -0
- data/lib/dry/types/constrained/coercible.rb +5 -0
- data/lib/dry/types/constraints.rb +3 -0
- data/lib/dry/types/constructor.rb +28 -0
- data/lib/dry/types/decorator.rb +19 -0
- data/lib/dry/types/default.rb +14 -0
- data/lib/dry/types/definition.rb +31 -4
- data/lib/dry/types/enum.rb +10 -1
- data/lib/dry/types/errors.rb +14 -2
- data/lib/dry/types/extensions/maybe.rb +19 -2
- data/lib/dry/types/hash.rb +18 -0
- data/lib/dry/types/hash/schema.rb +69 -0
- data/lib/dry/types/options.rb +6 -0
- data/lib/dry/types/result.rb +10 -0
- data/lib/dry/types/safe.rb +9 -0
- data/lib/dry/types/sum.rb +20 -0
- data/lib/dry/types/version.rb +1 -1
- metadata +23 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: b5aba3a0d92022b867e134a072196692b4f0d837
         | 
| 4 | 
            +
              data.tar.gz: d2a5c7e8b8c489ec5b507a92f92be026e7337d78
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b5c1a092cf9a157bdcbecc6aec42fa6731ab1e9a9067c81bb7e109a7516393128c0c183ceb4d589258bea87631da55735e38a4b44860f005ea2230b43985e406
         | 
| 7 | 
            +
              data.tar.gz: 706d91386ba41582d7eb927237790bf51c0790fc909b248b9a70c851070fb0f49e897e54098f51891fcd5afdd2ee7311fffb6deff7e8b9061b1b6b2135802743
         | 
    
        data/.travis.yml
    CHANGED
    
    | @@ -1,21 +1,25 @@ | |
| 1 1 | 
             
            language: ruby
         | 
| 2 | 
            -
             | 
| 2 | 
            +
            dist: trusty
         | 
| 3 | 
            +
            sudo: required
         | 
| 3 4 | 
             
            cache: bundler
         | 
| 4 5 | 
             
            bundler_args: --without benchmarks tools
         | 
| 6 | 
            +
            after_success:
         | 
| 7 | 
            +
              - '[ "$TRAVIS_RUBY_VERSION" = "2.3.1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
         | 
| 5 8 | 
             
            script:
         | 
| 6 9 | 
             
              - bundle exec rake
         | 
| 7 10 | 
             
            rvm:
         | 
| 8 | 
            -
              - 2.1 | 
| 9 | 
            -
              - 2.2 | 
| 10 | 
            -
              - 2.3 | 
| 11 | 
            +
              - 2.1
         | 
| 12 | 
            +
              - 2.2
         | 
| 13 | 
            +
              - 2.3
         | 
| 11 14 | 
             
              - jruby-9.1.5.0
         | 
| 12 | 
            -
              - rbx-3 | 
| 15 | 
            +
              - rbx-3
         | 
| 13 16 | 
             
            env:
         | 
| 14 17 | 
             
              global:
         | 
| 18 | 
            +
                - COVERAGE=true
         | 
| 15 19 | 
             
                - JRUBY_OPTS='--dev -J-Xmx1024M'
         | 
| 16 20 | 
             
            matrix:
         | 
| 17 21 | 
             
              allow_failures:
         | 
| 18 | 
            -
                - rvm: rbx-3 | 
| 22 | 
            +
                - rvm: rbx-3
         | 
| 19 23 | 
             
            notifications:
         | 
| 20 24 | 
             
              email: false
         | 
| 21 25 | 
             
              webhooks:
         | 
    
        data/.yardopts
    ADDED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,4 +1,12 @@ | |
| 1 | 
            -
            # v0.9. | 
| 1 | 
            +
            # v0.9.3 2016-12-03
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            ## Fixed
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Updated to dry-core >= 0.2.1 (ruby warnings are gone) (flash-gordon)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            [Compare v0.9.2...v0.9.3](https://github.com/dryrb/dry-types/compare/v0.9.2...v0.9.3)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # v0.9.2 2016-11-13
         | 
| 2 10 |  | 
| 3 11 | 
             
            ## Added
         | 
| 4 12 |  | 
    
        data/Gemfile
    CHANGED
    
    | @@ -3,7 +3,10 @@ source 'https://rubygems.org' | |
| 3 3 | 
             
            gemspec
         | 
| 4 4 |  | 
| 5 5 | 
             
            group :test do
         | 
| 6 | 
            -
               | 
| 6 | 
            +
              platform :mri do
         | 
| 7 | 
            +
                gem "codeclimate-test-reporter", require: false
         | 
| 8 | 
            +
                gem 'simplecov', require: false
         | 
| 9 | 
            +
              end
         | 
| 7 10 | 
             
            end
         | 
| 8 11 |  | 
| 9 12 | 
             
            group :tools do
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/dry-types.gemspec
    CHANGED
    
    | @@ -29,7 +29,7 @@ Gem::Specification.new do |spec| | |
| 29 29 | 
             
              spec.required_ruby_version = ">= 2.1.0"
         | 
| 30 30 |  | 
| 31 31 | 
             
              spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
         | 
| 32 | 
            -
              spec.add_runtime_dependency 'dry-core', '~> 0.2'
         | 
| 32 | 
            +
              spec.add_runtime_dependency 'dry-core', '~> 0.2', '>= 0.2.1'
         | 
| 33 33 | 
             
              spec.add_runtime_dependency 'dry-container', '~> 0.3'
         | 
| 34 34 | 
             
              spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
         | 
| 35 35 | 
             
              spec.add_runtime_dependency 'dry-configurable', '~> 0.1'
         | 
| @@ -40,4 +40,5 @@ Gem::Specification.new do |spec| | |
| 40 40 | 
             
              spec.add_development_dependency "rake", "~> 11.0"
         | 
| 41 41 | 
             
              spec.add_development_dependency "rspec", "~> 3.3"
         | 
| 42 42 | 
             
              spec.add_development_dependency 'dry-monads', '~> 0.2'
         | 
| 43 | 
            +
              spec.add_development_dependency 'yard', '~> 0.9.5'
         | 
| 43 44 | 
             
            end
         | 
    
        data/lib/dry/types.rb
    CHANGED
    
    | @@ -8,6 +8,7 @@ require 'concurrent' | |
| 8 8 | 
             
            require 'dry-container'
         | 
| 9 9 | 
             
            require 'dry-equalizer'
         | 
| 10 10 | 
             
            require 'dry/core/extensions'
         | 
| 11 | 
            +
            require 'dry/core/constants'
         | 
| 11 12 |  | 
| 12 13 | 
             
            require 'dry/types/version'
         | 
| 13 14 | 
             
            require 'dry/types/container'
         | 
| @@ -20,17 +21,22 @@ module Dry | |
| 20 21 | 
             
              module Types
         | 
| 21 22 | 
             
                extend Dry::Configurable
         | 
| 22 23 | 
             
                extend Dry::Core::Extensions
         | 
| 24 | 
            +
                include Dry::Core::Constants
         | 
| 23 25 |  | 
| 26 | 
            +
                # @!attribute [r] namespace
         | 
| 27 | 
            +
                #   @return [Container{String => Definition}]
         | 
| 24 28 | 
             
                setting :namespace, self
         | 
| 25 29 |  | 
| 26 30 | 
             
                TYPE_SPEC_REGEX = %r[(.+)<(.+)>].freeze
         | 
| 27 31 |  | 
| 32 | 
            +
                # @return [Module]
         | 
| 28 33 | 
             
                def self.module
         | 
| 29 34 | 
             
                  namespace = Module.new
         | 
| 30 35 | 
             
                  define_constants(namespace, type_keys)
         | 
| 31 36 | 
             
                  namespace
         | 
| 32 37 | 
             
                end
         | 
| 33 38 |  | 
| 39 | 
            +
                # @deprecated Include {Dry::Types.module} instead
         | 
| 34 40 | 
             
                def self.finalize
         | 
| 35 41 | 
             
                  warn 'Dry::Types.finalize and configuring namespace is deprecated. Just'\
         | 
| 36 42 | 
             
                   ' do `include Dry::Types.module` in places where you want to have access'\
         | 
| @@ -39,19 +45,30 @@ module Dry | |
| 39 45 | 
             
                  define_constants(config.namespace, type_keys)
         | 
| 40 46 | 
             
                end
         | 
| 41 47 |  | 
| 48 | 
            +
                # @return [Container{String => Definition}]
         | 
| 42 49 | 
             
                def self.container
         | 
| 43 50 | 
             
                  @container ||= Container.new
         | 
| 44 51 | 
             
                end
         | 
| 45 52 |  | 
| 53 | 
            +
                # @param [String] name
         | 
| 54 | 
            +
                # @param [Definition] type
         | 
| 55 | 
            +
                # @param [#call] block
         | 
| 56 | 
            +
                # @return [Container{String => Definition}]
         | 
| 46 57 | 
             
                def self.register(name, type = nil, &block)
         | 
| 47 58 | 
             
                  container.register(name, type || block.call)
         | 
| 48 59 | 
             
                end
         | 
| 49 60 |  | 
| 61 | 
            +
                # Registers given +klass+ in {#container} using +meth+ constructor
         | 
| 62 | 
            +
                # @param [Class] klass
         | 
| 63 | 
            +
                # @param [Symbol] meth
         | 
| 64 | 
            +
                # @return [Container{String => Definition}]
         | 
| 50 65 | 
             
                def self.register_class(klass, meth = :new)
         | 
| 51 66 | 
             
                  type = Definition.new(klass).constructor(klass.method(meth))
         | 
| 52 67 | 
             
                  container.register(identifier(klass), type)
         | 
| 53 68 | 
             
                end
         | 
| 54 69 |  | 
| 70 | 
            +
                # @param [String] name
         | 
| 71 | 
            +
                # @return [Definition]
         | 
| 55 72 | 
             
                def self.[](name)
         | 
| 56 73 | 
             
                  type_map.fetch_or_store(name) do
         | 
| 57 74 | 
             
                    case name
         | 
| @@ -76,6 +93,9 @@ module Dry | |
| 76 93 | 
             
                  end
         | 
| 77 94 | 
             
                end
         | 
| 78 95 |  | 
| 96 | 
            +
                # @param [Container{String => Definition}] namespace
         | 
| 97 | 
            +
                # @param [<String>] identifiers
         | 
| 98 | 
            +
                # @return [<Definition>]
         | 
| 79 99 | 
             
                def self.define_constants(namespace, identifiers)
         | 
| 80 100 | 
             
                  names = identifiers.map do |id|
         | 
| 81 101 | 
             
                    parts = id.split('.')
         | 
| @@ -91,14 +111,19 @@ module Dry | |
| 91 111 | 
             
                  end
         | 
| 92 112 | 
             
                end
         | 
| 93 113 |  | 
| 114 | 
            +
                # @param [#to_s] klass
         | 
| 115 | 
            +
                # @return [String]
         | 
| 94 116 | 
             
                def self.identifier(klass)
         | 
| 95 117 | 
             
                  Inflecto.underscore(klass).tr('/', '.')
         | 
| 96 118 | 
             
                end
         | 
| 97 119 |  | 
| 120 | 
            +
                # @return [Concurrent::Map]
         | 
| 98 121 | 
             
                def self.type_map
         | 
| 99 122 | 
             
                  @type_map ||= Concurrent::Map.new
         | 
| 100 123 | 
             
                end
         | 
| 101 124 |  | 
| 125 | 
            +
                # List of type keys defined in {Dry::Types.container}
         | 
| 126 | 
            +
                # @return [<String>]
         | 
| 102 127 | 
             
                def self.type_keys
         | 
| 103 128 | 
             
                  container._container.keys
         | 
| 104 129 | 
             
                end
         | 
    
        data/lib/dry/types/array.rb
    CHANGED
    
    
| @@ -2,22 +2,36 @@ module Dry | |
| 2 2 | 
             
              module Types
         | 
| 3 3 | 
             
                class Array < Definition
         | 
| 4 4 | 
             
                  class Member < Array
         | 
| 5 | 
            +
                    # @return [Definition]
         | 
| 5 6 | 
             
                    attr_reader :member
         | 
| 6 7 |  | 
| 8 | 
            +
                    # @param [Class] primitive
         | 
| 9 | 
            +
                    # @param [Hash] options
         | 
| 10 | 
            +
                    # @option options [Definition] :member
         | 
| 7 11 | 
             
                    def initialize(primitive, options = {})
         | 
| 8 12 | 
             
                      @member = options.fetch(:member)
         | 
| 9 13 | 
             
                      super
         | 
| 10 14 | 
             
                    end
         | 
| 11 15 |  | 
| 16 | 
            +
                    # @param [Object] input
         | 
| 17 | 
            +
                    # @param [Symbol] meth
         | 
| 18 | 
            +
                    # @return [Array]
         | 
| 12 19 | 
             
                    def call(input, meth = :call)
         | 
| 13 20 | 
             
                      input.map { |el| member.__send__(meth, el) }
         | 
| 14 21 | 
             
                    end
         | 
| 15 22 | 
             
                    alias_method :[], :call
         | 
| 16 23 |  | 
| 17 | 
            -
                     | 
| 18 | 
            -
             | 
| 24 | 
            +
                    # @param [Array, #all?] value
         | 
| 25 | 
            +
                    # @return [Boolean]
         | 
| 26 | 
            +
                    def valid?(value)
         | 
| 27 | 
            +
                      super && value.all? { |el| member.valid?(el) }
         | 
| 19 28 | 
             
                    end
         | 
| 20 29 |  | 
| 30 | 
            +
                    # @param [Array, Object] input
         | 
| 31 | 
            +
                    # @param [#call] block
         | 
| 32 | 
            +
                    # @yieldparam [Failure] failure
         | 
| 33 | 
            +
                    # @yieldreturn [Result]
         | 
| 34 | 
            +
                    # @return [Result]
         | 
| 21 35 | 
             
                    def try(input, &block)
         | 
| 22 36 | 
             
                      if input.is_a?(::Array)
         | 
| 23 37 | 
             
                        result = call(input, :try)
         | 
    
        data/lib/dry/types/builder.rb
    CHANGED
    
    | @@ -1,27 +1,35 @@ | |
| 1 | 
            -
            require 'dry/core/constants'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module Dry
         | 
| 4 2 | 
             
              module Types
         | 
| 5 3 | 
             
                module Builder
         | 
| 6 4 | 
             
                  include Dry::Core::Constants
         | 
| 7 5 |  | 
| 6 | 
            +
                  # @return [Constrained]
         | 
| 8 7 | 
             
                  def constrained_type
         | 
| 9 8 | 
             
                    Constrained
         | 
| 10 9 | 
             
                  end
         | 
| 11 10 |  | 
| 11 | 
            +
                  # @param [Definition] other
         | 
| 12 | 
            +
                  # @return [Sum, Sum::Constrained]
         | 
| 12 13 | 
             
                  def |(other)
         | 
| 13 14 | 
             
                    klass = constrained? && other.constrained? ? Sum::Constrained : Sum
         | 
| 14 15 | 
             
                    klass.new(self, other)
         | 
| 15 16 | 
             
                  end
         | 
| 16 17 |  | 
| 18 | 
            +
                  # @return [Sum]
         | 
| 17 19 | 
             
                  def optional
         | 
| 18 20 | 
             
                    Types['strict.nil'] | self
         | 
| 19 21 | 
             
                  end
         | 
| 20 22 |  | 
| 23 | 
            +
                  # @param [Hash] options constraining rule (see {Types.Rule})
         | 
| 24 | 
            +
                  # @return [Constrained]
         | 
| 21 25 | 
             
                  def constrained(options)
         | 
| 22 26 | 
             
                    constrained_type.new(self, rule: Types.Rule(options))
         | 
| 23 27 | 
             
                  end
         | 
| 24 28 |  | 
| 29 | 
            +
                  # @param [Object] input
         | 
| 30 | 
            +
                  # @param [#call] block
         | 
| 31 | 
            +
                  # @raise [ConstraintError]
         | 
| 32 | 
            +
                  # @return [Default]
         | 
| 25 33 | 
             
                  def default(input = Undefined, &block)
         | 
| 26 34 | 
             
                    value = input == Undefined ? block : input
         | 
| 27 35 |  | 
| @@ -32,14 +40,21 @@ module Dry | |
| 32 40 | 
             
                    end
         | 
| 33 41 | 
             
                  end
         | 
| 34 42 |  | 
| 43 | 
            +
                  # @param [Array] values
         | 
| 44 | 
            +
                  # @return [Enum]
         | 
| 35 45 | 
             
                  def enum(*values)
         | 
| 36 46 | 
             
                    Enum.new(constrained(included_in: values), values: values)
         | 
| 37 47 | 
             
                  end
         | 
| 38 48 |  | 
| 49 | 
            +
                  # @return [Safe]
         | 
| 39 50 | 
             
                  def safe
         | 
| 40 51 | 
             
                    Safe.new(self)
         | 
| 41 52 | 
             
                  end
         | 
| 42 53 |  | 
| 54 | 
            +
                  # @param [#call] constructor
         | 
| 55 | 
            +
                  # @param [Hash] options
         | 
| 56 | 
            +
                  # @param [#call] block
         | 
| 57 | 
            +
                  # @return [Constructor]
         | 
| 43 58 | 
             
                  def constructor(constructor = nil, **options, &block)
         | 
| 44 59 | 
             
                    Constructor.new(with(options), fn: constructor || block)
         | 
| 45 60 | 
             
                  end
         | 
    
        data/lib/dry/types/coercions.rb
    CHANGED
    
    | @@ -1,14 +1,17 @@ | |
| 1 | 
            -
            require 'dry/core/constants'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module Dry
         | 
| 4 2 | 
             
              module Types
         | 
| 5 3 | 
             
                module Coercions
         | 
| 6 4 | 
             
                  include Dry::Core::Constants
         | 
| 7 5 |  | 
| 6 | 
            +
                  # @param [String] input
         | 
| 7 | 
            +
                  # @return [String?]
         | 
| 8 8 | 
             
                  def to_nil(input)
         | 
| 9 9 | 
             
                    input unless empty_str?(input)
         | 
| 10 10 | 
             
                  end
         | 
| 11 11 |  | 
| 12 | 
            +
                  # @param [#to_str, Object] input
         | 
| 13 | 
            +
                  # @return [Date, Object]
         | 
| 14 | 
            +
                  # @see Date.parse
         | 
| 12 15 | 
             
                  def to_date(input)
         | 
| 13 16 | 
             
                    return input unless input.respond_to?(:to_str)
         | 
| 14 17 | 
             
                    Date.parse(input)
         | 
| @@ -16,6 +19,9 @@ module Dry | |
| 16 19 | 
             
                    input
         | 
| 17 20 | 
             
                  end
         | 
| 18 21 |  | 
| 22 | 
            +
                  # @param [#to_str, Object] input
         | 
| 23 | 
            +
                  # @return [DateTime, Object]
         | 
| 24 | 
            +
                  # @see DateTime.parse
         | 
| 19 25 | 
             
                  def to_date_time(input)
         | 
| 20 26 | 
             
                    return input unless input.respond_to?(:to_str)
         | 
| 21 27 | 
             
                    DateTime.parse(input)
         | 
| @@ -23,6 +29,9 @@ module Dry | |
| 23 29 | 
             
                    input
         | 
| 24 30 | 
             
                  end
         | 
| 25 31 |  | 
| 32 | 
            +
                  # @param [#to_str, Object] input
         | 
| 33 | 
            +
                  # @return [Time, Object]
         | 
| 34 | 
            +
                  # @see Time.parse
         | 
| 26 35 | 
             
                  def to_time(input)
         | 
| 27 36 | 
             
                    return input unless input.respond_to?(:to_str)
         | 
| 28 37 | 
             
                    Time.parse(input)
         | 
| @@ -32,6 +41,9 @@ module Dry | |
| 32 41 |  | 
| 33 42 | 
             
                  private
         | 
| 34 43 |  | 
| 44 | 
            +
                  # Checks whether String is empty
         | 
| 45 | 
            +
                  # @param [String, Object] value
         | 
| 46 | 
            +
                  # @return [Boolean]
         | 
| 35 47 | 
             
                  def empty_str?(value)
         | 
| 36 48 | 
             
                    EMPTY_STRING.eql?(value)
         | 
| 37 49 | 
             
                  end
         | 
| @@ -11,14 +11,24 @@ module Dry | |
| 11 11 |  | 
| 12 12 | 
             
                    extend Coercions
         | 
| 13 13 |  | 
| 14 | 
            +
                    # @param [String, Object] input
         | 
| 15 | 
            +
                    # @return [Boolean?]
         | 
| 16 | 
            +
                    # @see TRUE_VALUES
         | 
| 17 | 
            +
                    # @see FALSE_VALUES
         | 
| 14 18 | 
             
                    def self.to_true(input)
         | 
| 15 19 | 
             
                      BOOLEAN_MAP.fetch(input.to_s, input)
         | 
| 16 20 | 
             
                    end
         | 
| 17 21 |  | 
| 22 | 
            +
                    # @param [String, Object] input
         | 
| 23 | 
            +
                    # @return [Boolean?]
         | 
| 24 | 
            +
                    # @see TRUE_VALUES
         | 
| 25 | 
            +
                    # @see FALSE_VALUES
         | 
| 18 26 | 
             
                    def self.to_false(input)
         | 
| 19 27 | 
             
                      BOOLEAN_MAP.fetch(input.to_s, input)
         | 
| 20 28 | 
             
                    end
         | 
| 21 29 |  | 
| 30 | 
            +
                    # @param [#to_int, #to_i, Object] input
         | 
| 31 | 
            +
                    # @return [Integer?, Object]
         | 
| 22 32 | 
             
                    def self.to_int(input)
         | 
| 23 33 | 
             
                      if empty_str?(input)
         | 
| 24 34 | 
             
                        nil
         | 
| @@ -29,6 +39,8 @@ module Dry | |
| 29 39 | 
             
                      input
         | 
| 30 40 | 
             
                    end
         | 
| 31 41 |  | 
| 42 | 
            +
                    # @param [#to_f, Object] input
         | 
| 43 | 
            +
                    # @return [Float?, Object]
         | 
| 32 44 | 
             
                    def self.to_float(input)
         | 
| 33 45 | 
             
                      if empty_str?(input)
         | 
| 34 46 | 
             
                        nil
         | 
| @@ -39,6 +51,8 @@ module Dry | |
| 39 51 | 
             
                      input
         | 
| 40 52 | 
             
                    end
         | 
| 41 53 |  | 
| 54 | 
            +
                    # @param [#to_d, Object] input
         | 
| 55 | 
            +
                    # @return [BigDecimal?, Object]
         | 
| 42 56 | 
             
                    def self.to_decimal(input)
         | 
| 43 57 | 
             
                      result = to_float(input)
         | 
| 44 58 |  | 
| @@ -49,10 +63,14 @@ module Dry | |
| 49 63 | 
             
                      end
         | 
| 50 64 | 
             
                    end
         | 
| 51 65 |  | 
| 66 | 
            +
                    # @param [Array, '', Object] input
         | 
| 67 | 
            +
                    # @return [Array, Object]
         | 
| 52 68 | 
             
                    def self.to_ary(input)
         | 
| 53 69 | 
             
                      empty_str?(input) ? [] : input
         | 
| 54 70 | 
             
                    end
         | 
| 55 71 |  | 
| 72 | 
            +
                    # @param [Hash, '', Object] input
         | 
| 73 | 
            +
                    # @return [Hash]
         | 
| 56 74 | 
             
                    def self.to_hash(input)
         | 
| 57 75 | 
             
                      empty_str?(input) ? {} : input
         | 
| 58 76 | 
             
                    end
         | 
| @@ -9,13 +9,19 @@ module Dry | |
| 9 9 | 
             
                  include Decorator
         | 
| 10 10 | 
             
                  include Builder
         | 
| 11 11 |  | 
| 12 | 
            +
                  # @return [Dry::Logic::Rule]
         | 
| 12 13 | 
             
                  attr_reader :rule
         | 
| 13 14 |  | 
| 15 | 
            +
                  # @param [Definition] type
         | 
| 16 | 
            +
                  # @param [Hash] options
         | 
| 14 17 | 
             
                  def initialize(type, options)
         | 
| 15 18 | 
             
                    super
         | 
| 16 19 | 
             
                    @rule = options.fetch(:rule)
         | 
| 17 20 | 
             
                  end
         | 
| 18 21 |  | 
| 22 | 
            +
                  # @param [Object] input
         | 
| 23 | 
            +
                  # @return [Object]
         | 
| 24 | 
            +
                  # @raise [ConstraintError]
         | 
| 19 25 | 
             
                  def call(input)
         | 
| 20 26 | 
             
                    try(input) do |result|
         | 
| 21 27 | 
             
                      raise ConstraintError.new(result, input)
         | 
| @@ -23,6 +29,11 @@ module Dry | |
| 23 29 | 
             
                  end
         | 
| 24 30 | 
             
                  alias_method :[], :call
         | 
| 25 31 |  | 
| 32 | 
            +
                  # @param [Object] input
         | 
| 33 | 
            +
                  # @param [#call] block
         | 
| 34 | 
            +
                  # @yieldparam [Failure] failure
         | 
| 35 | 
            +
                  # @yieldreturn [Result]
         | 
| 36 | 
            +
                  # @return [Result]
         | 
| 26 37 | 
             
                  def try(input, &block)
         | 
| 27 38 | 
             
                    result = rule.(input)
         | 
| 28 39 |  | 
| @@ -34,20 +45,30 @@ module Dry | |
| 34 45 | 
             
                    end
         | 
| 35 46 | 
             
                  end
         | 
| 36 47 |  | 
| 48 | 
            +
                  # @param [Object] value
         | 
| 49 | 
            +
                  # @return [Boolean]
         | 
| 37 50 | 
             
                  def valid?(value)
         | 
| 38 51 | 
             
                    rule.(value).success? && type.valid?(value)
         | 
| 39 52 | 
             
                  end
         | 
| 40 53 |  | 
| 54 | 
            +
                  # @param [Hash] options
         | 
| 55 | 
            +
                  #   The options hash provided to {Types.Rule} and combined
         | 
| 56 | 
            +
                  #   using {&} with previous {#rule}
         | 
| 57 | 
            +
                  # @return [Constrained]
         | 
| 58 | 
            +
                  # @see Dry::Logic::Operators#and
         | 
| 41 59 | 
             
                  def constrained(options)
         | 
| 42 60 | 
             
                    with(rule: rule & Types.Rule(options))
         | 
| 43 61 | 
             
                  end
         | 
| 44 62 |  | 
| 63 | 
            +
                  # @return [true]
         | 
| 45 64 | 
             
                  def constrained?
         | 
| 46 65 | 
             
                    true
         | 
| 47 66 | 
             
                  end
         | 
| 48 67 |  | 
| 49 68 | 
             
                  private
         | 
| 50 69 |  | 
| 70 | 
            +
                  # @param [Object] response
         | 
| 71 | 
            +
                  # @return [Boolean]
         | 
| 51 72 | 
             
                  def decorate?(response)
         | 
| 52 73 | 
             
                    super || response.kind_of?(Constructor)
         | 
| 53 74 | 
             
                  end
         |