Module: Dry::Types

Extended by:
Core::ClassAttributes, Core::Extensions
Includes:
Core::Constants
Defined in:
lib/dry/types.rb,
lib/dry/types/any.rb,
lib/dry/types/lax.rb,
lib/dry/types/map.rb,
lib/dry/types/sum.rb,
lib/dry/types/core.rb,
lib/dry/types/enum.rb,
lib/dry/types/hash.rb,
lib/dry/types/json.rb,
lib/dry/types/meta.rb,
lib/dry/types/type.rb,
lib/dry/types/array.rb,
lib/dry/types/errors.rb,
lib/dry/types/module.rb,
lib/dry/types/params.rb,
lib/dry/types/result.rb,
lib/dry/types/schema.rb,
lib/dry/types/builder.rb,
lib/dry/types/default.rb,
lib/dry/types/nominal.rb,
lib/dry/types/options.rb,
lib/dry/types/printer.rb,
lib/dry/types/version.rb,
lib/dry/types/compiler.rb,
lib/dry/types/coercions.rb,
lib/dry/types/container.rb,
lib/dry/types/decorator.rb,
lib/dry/types/inflector.rb,
lib/dry/types/printable.rb,
lib/dry/types/schema/key.rb,
lib/dry/types/composition.rb,
lib/dry/types/constrained.rb,
lib/dry/types/constraints.rb,
lib/dry/types/constructor.rb,
lib/dry/types/implication.rb,
lib/dry/types/array/member.rb,
lib/dry/types/fn_container.rb,
lib/dry/types/intersection.rb,
lib/dry/types/coercions/json.rb,
lib/dry/types/builder_methods.rb,
lib/dry/types/coercions/params.rb,
lib/dry/types/extensions/maybe.rb,
lib/dry/types/hash/constructor.rb,
lib/dry/types/array/constructor.rb,
lib/dry/types/extensions/monads.rb,
lib/dry/types/predicate_inferrer.rb,
lib/dry/types/predicate_registry.rb,
lib/dry/types/primitive_inferrer.rb,
lib/dry/types/constructor/wrapper.rb,
lib/dry/types/printer/composition.rb,
lib/dry/types/constructor/function.rb,
lib/dry/types/constrained/coercible.rb

Overview

Helper methods for constraint types

Defined Under Namespace

Modules: Builder, BuilderMethods, Coercions, Composition, Decorator, Meta, Options, Printable, Type Classes: AnyClass, Array, CoercionError, Compiler, Constrained, ConstraintError, Constructor, Container, Default, Enum, FnContainer, Hash, Implication, Intersection, Lax, Map, Maybe, MissingKeyError, Module, MultipleError, Nominal, PredicateInferrer, PredicateRegistry, PrimitiveInferrer, Printer, Result, Schema, SchemaError, Sum, UnknownKeysError

Constant Summary collapse

TYPE_SPEC_REGEX =
/(.+)<(.+)>/
Any =
AnyClass.new
Safe =
Lax
KERNEL_COERCIBLE =

Primitives with Kernel coercion methods

{
  string: String,
  integer: Integer,
  float: Float,
  decimal: BigDecimal,
  array: ::Array,
  hash: ::Hash
}.freeze
METHOD_COERCIBLE =

Primitives with coercions through by convention to_* methods

{
  symbol: Symbol
}.freeze
METHOD_COERCIBLE_METHODS =

By convention methods to coerce METHOD_COERCIBLE primitives

{
  symbol: :to_sym
}.freeze
NON_COERCIBLE =

Primitives that are non-coercible

{
  nil: NilClass,
  class: Class,
  true: TrueClass,
  false: FalseClass,
  date: Date,
  date_time: DateTime,
  time: Time,
  range: Range
}.freeze
ALL_PRIMITIVES =

All built-in primitives

[
  KERNEL_COERCIBLE, METHOD_COERCIBLE, NON_COERCIBLE
].reduce(&:merge).freeze
COERCIBLE =

All coercible types

KERNEL_COERCIBLE.merge(METHOD_COERCIBLE).freeze
NON_NIL =

All built-in primitives except NilClass

ALL_PRIMITIVES.except(:nil).freeze
MapError =
::Class.new(CoercionError)
Definition =
Nominal
PRINTER =
Printer.new
VERSION =
"1.9.0"
Inflector =
::Dry::Inflector.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#namespaceContainer{String => Nominal} (readonly)

Returns:



9
# File 'lib/dry/types/errors.rb', line 9

defines :namespace

Class Method Details

.[](name) ⇒ Type, Class

Get a built-in type by its name

Parameters:

  • name (String, Class)

Returns:



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/dry/types.rb', line 114

def self.[](name)
  type_map.fetch_or_store(name) do
    case name
    when ::String
      result = name.match(TYPE_SPEC_REGEX)

      if result
        type_id, member_id = result[1..2]
        container[type_id].of(self[member_id])
      else
        container[name]
      end
    when ::Class
      warn(<<~DEPRECATION)
        Using Dry::Types.[] with a class is deprecated, please use string identifiers: Dry::Types[Integer] -> Dry::Types['integer'].
        If you're using dry-struct this means changing `attribute :counter, Integer` to `attribute :counter, Dry::Types['integer']` or to `attribute :counter, 'integer'`.
      DEPRECATION

      type_name = identifier(name)

      if container.key?(type_name)
        self[type_name]
      else
        name
      end
    end
  end
end

.const_missing(const) ⇒ Object

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.



162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/dry/types.rb', line 162

def self.const_missing(const)
  underscored = Types::Inflector.underscore(const)

  if container.keys.any? { |key| key.split(".")[0] == underscored }
    raise ::NameError,
          "dry-types does not define constants for default types. " \
          "You can access the predefined types with [], e.g. Dry::Types['integer'] " \
          "or generate a module with types using Dry.Types()"
  else
    super
  end
end

.containerContainer{String => Nominal}

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.

Return container with registered built-in type objects

Returns:



81
82
83
# File 'lib/dry/types.rb', line 81

def self.container
  @container ||= Container.new
end

.define_builder(method, &block) ⇒ Object

Add a new type builder method. This is a public API for defining custom type constructors

Examples:

simple custom type constructor

Dry::Types.define_builder(:or_nil) do |type|
  type.optional.fallback(nil)
end

Dry::Types["integer"].or_nil.("foo") # => nil

fallback alias

Dry::Types.define_builder(:or) do |type, fallback|
  type.fallback(fallback)
end

Dry::Types["integer"].or(100).("foo") # => 100

Parameters:

  • method (Symbol)
  • block (#call)


196
197
198
199
200
# File 'lib/dry/types.rb', line 196

def self.define_builder(method, &block)
  Builder.define_method(method) do |*args|
    block.(self, *args)
  end
end

.identifier(klass) ⇒ String

Infer a type identifier from the provided class

Parameters:

  • klass (#to_s)

Returns:

  • (String)


148
149
150
# File 'lib/dry/types.rb', line 148

def self.identifier(klass)
  Types::Inflector.underscore(klass).tr("/", ".")
end

.includedObject

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.



74
# File 'lib/dry/types.rb', line 74

def self.included(*) = raise "Import Dry.Types, not Dry::Types"

.loaderObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/dry/types.rb', line 32

def self.loader
  @loader ||= ::Zeitwerk::Loader.new.tap do |loader|
    root = ::File.expand_path("..", __dir__)
    loader.tag = "dry-types"
    loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-types.rb")
    loader.inflector.inflect("json" => "JSON")
    loader.push_dir(root)
    loader.ignore(
      "#{root}/dry-types.rb",
      "#{root}/dry/types/extensions",
      "#{root}/dry/types/printer",
      "#{root}/dry/types/spec/types.rb",
      "#{root}/dry/types/{#{%w[
        compat constraints core
        errors extensions inflector
        module json params
        printer version
      ].join(",")}}.rb"
    )
  end
end

.module(*namespaces, default: :nominal, **aliases) ⇒ Object



66
67
68
# File 'lib/dry/types.rb', line 66

def self.module(*namespaces, default: :nominal, **aliases)
  ::Module.new(container, *namespaces, default: default, **aliases)
end

.register(name, type = nil, &block) ⇒ Container{String => Nominal}

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.

Register a new built-in type

Parameters:

  • name (String)
  • type (Type) (defaults to: nil)
  • block (#call, nil)

Returns:



103
104
105
# File 'lib/dry/types.rb', line 103

def self.register(name, type = nil, &block)
  container.register(name, type || block.call)
end

.registered?(class_or_identifier) ⇒ Boolean

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.

Check if a give type is registered

Returns:

  • (Boolean)


90
91
92
# File 'lib/dry/types.rb', line 90

def self.registered?(class_or_identifier)
  container.key?(identifier(class_or_identifier))
end

.Rule(options) ⇒ Dry::Logic::Rule

Parameters:

Returns:

  • (Dry::Logic::Rule)


13
14
15
16
17
18
19
20
21
# File 'lib/dry/types/constraints.rb', line 13

def self.Rule(options)
  rule_compiler.(
    options.map { |key, val|
      ::Dry::Logic::Rule::Predicate.build(
        ::Dry::Logic::Predicates[:"#{key}?"]
      ).curry(val).to_ast
    }
  ).reduce(:and)
end

.rule_compilerDry::Logic::RuleCompiler

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.

Returns:

  • (Dry::Logic::RuleCompiler)


26
27
28
# File 'lib/dry/types/constraints.rb', line 26

def self.rule_compiler
  @rule_compiler ||= ::Dry::Logic::RuleCompiler.new(::Dry::Logic::Predicates)
end

.type_mapConcurrent::Map

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.

Cached type map

Returns:

  • (Concurrent::Map)


157
158
159
# File 'lib/dry/types.rb', line 157

def self.type_map
  @type_map ||= ::Concurrent::Map.new
end