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.reject { |name, _| name == :nil }.freeze
MapError =
::Class.new(CoercionError)
Definition =
Nominal
PRINTER =
Printer.new
VERSION =
"1.7.2"
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:



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
142
# File 'lib/dry/types.rb', line 115

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.



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

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:



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

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)


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

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)


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

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.



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

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

.loaderObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dry/types.rb', line 33

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



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

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:



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

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)


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

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)


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

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