Module: Dry::Types::Builder

Includes:
Core::Constants
Included in:
Composition, Constrained, Default, Enum, Lax, Maybe, Nominal, Schema::Key
Defined in:
lib/dry/types/builder.rb,
lib/dry/types/extensions/maybe.rb

Overview

Common API for building types and composition

Instance Method Summary collapse

Instance Method Details

#&(other) ⇒ Intersection, Intersection::Constrained

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Compose two types into an Intersection type



37
# File 'lib/dry/types/builder.rb', line 37

def &(other) = compose(other, Intersection)

#>(other) ⇒ Implication, Implication::Constrained

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Compose two types into an Implication type



46
# File 'lib/dry/types/builder.rb', line 46

def >(other) = compose(other, Implication)

#constrainedConstrained

Turn a type into a constrained type



71
72
73
# File 'lib/dry/types/builder.rb', line 71

def constrained(...)
  constrained_type.new(self, rule: Types.Rule(...))
end

#constrained_typeClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



14
# File 'lib/dry/types/builder.rb', line 14

def constrained_type = Constrained

#constructor(constructor = nil, **options, &block) ⇒ Constructor Also known as: append, prepend, >>, <<

Define a constructor for the type



154
155
156
# File 'lib/dry/types/builder.rb', line 154

def constructor(constructor = nil, **options, &block)
  constructor_type[with(**options), fn: constructor || block]
end

#constructor_typeClass

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



19
# File 'lib/dry/types/builder.rb', line 19

def constructor_type = Constructor

#default(input = Undefined, options = EMPTY_HASH, &block) ⇒ Default

Turn a type into a type with a default value

Raises:



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/dry/types/builder.rb', line 86

def default(input = Undefined, options = EMPTY_HASH, &block)
  unless input.frozen? || options[:shared]
    where = Core::Deprecations::STACK.()

    # There is a weird behaviour in JRuby where the source_location is mutated upon
    # calling `inspect` on proc (see: https://github.com/jruby/jruby/issues/9110)
    # To bypass this, we call inspect on the clone (but only for proc and JRuby).
    # This should be fixes in JRuby 10.0.3.0.
    obj = input.is_a?(Proc) && RUBY_ENGINE == "jruby" ? input.dup : input

    Core::Deprecations.warn(
      "#{obj.inspect} is mutable. " \
      "Be careful: types will return the same instance of the default " \
      "value every time. Call `.freeze` when setting the default " \
      "or pass `shared: true` to discard this warning." \
      "\n#{where}",
      tag: :"dry-types"
    )
  end

  value = Undefined.default(input, block)
  type = Default[value].new(self, value)

  if !type.callable? && !valid?(value)
    raise ConstraintError.new(
      "default value #{value.inspect} violates constraints",
      value
    )
  else
    type
  end
end

#enum(*values) ⇒ Enum

Define an enum on top of the existing type



126
127
128
129
130
131
132
133
134
135
# File 'lib/dry/types/builder.rb', line 126

def enum(*values)
  mapping =
    if values.length == 1 && values[0].is_a?(::Hash)
      values[0]
    else
      values.zip(values).to_h
    end

  Enum.new(constrained(included_in: mapping.keys), mapping: mapping)
end

#fallback(value = Undefined, shared: false, &_fallback) ⇒ Constructor

Use the given value on type mismatch



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/dry/types/builder.rb', line 171

def fallback(value = Undefined, shared: false, &_fallback) # rubocop:disable Metrics/PerceivedComplexity
  if Undefined.equal?(value) && !block_given?
    raise ::ArgumentError, "fallback value or a block must be given"
  end

  if !block_given? && !valid?(value)
    raise ConstraintError.new(
      "fallback value #{value.inspect} violates constraints",
      value
    )
  end

  unless value.frozen? || shared
    where = Core::Deprecations::STACK.()
    Core::Deprecations.warn(
      "#{value.inspect} is mutable. " \
      "Be careful: types will return the same instance of the fallback " \
      "value every time. Call `.freeze` when setting the fallback " \
      "or pass `shared: true` to discard this warning." \
      "\n#{where}",
      tag: :"dry-types"
    )
  end

  constructor do |input, type, &|
    type.(input) do |output = input|
      if block_given?
        yield(output)
      else
        value
      end
    end
  end
end

#laxLax

Turn a type into a lax type that will rescue from type-errors and return the original input



143
# File 'lib/dry/types/builder.rb', line 143

def lax = Lax.new(self)

#maybeMaybe

Turn a type into a maybe type



97
# File 'lib/dry/types/extensions/maybe.rb', line 97

def maybe = Maybe.new(Types["nil"] | self)

#optionalSum

Turn a type into an optional type



53
54
55
56
57
58
59
60
61
62
# File 'lib/dry/types/builder.rb', line 53

def optional
  nil_type =
    if Types.use_namespaced_optionals && respond_to?(:namespace) && namespace
      Types["#{namespace}.nil"]
    else
      Types["nil"]
    end

  nil_type | self
end

#|(other) ⇒ Sum, Sum::Constrained

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Compose two types into a Sum type



28
# File 'lib/dry/types/builder.rb', line 28

def |(other) = compose(other, Sum)