module Dry::Types

Main library namespace

@api public

Helper methods for constraint types

@api public

rubocop:disable Metrics/AbcSize rubocop:disable Metrics/PerceivedComplexity

Constants

ALL_PRIMITIVES

All built-in primitives

Any
COERCIBLE

All coercible types

Definition

Nominal types define a primitive class and do not apply any constructors or constraints

Use these types for annotations and the base for building more complex types on top of them.

@api public

Inflector
KERNEL_COERCIBLE

Primitives with {Kernel} coercion methods

METHOD_COERCIBLE

Primitives with coercions through by convention ‘to_*` methods

METHOD_COERCIBLE_METHODS

By convention methods to coerce {METHOD_COERCIBLE} primitives

MapError
NON_COERCIBLE

Primitives that are non-coercible

NON_NIL

All built-in primitives except {NilClass}

PRINTER
Safe

Lax types rescue from type-related errors when constructors fail

@api public

SchemaKeyError
TYPE_SPEC_REGEX
VERSION

Public Class Methods

Rule(options) click to toggle source

@param [Hash] options

@return [Dry::Logic::Rule]

@api public

# 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
[](name) click to toggle source

Get a built-in type by its name

@param [String,Class] name

@return [Type,Class]

@api public

# 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) click to toggle source

@api private

Calls superclass method
# 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
container() click to toggle source

Return container with registered built-in type objects

@return [Container{String => Nominal}]

@api private

# File lib/dry/types.rb, line 82
def self.container
  @container ||= Container.new
end
define_builder(method, &block) click to toggle source

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

@example simple custom type constructor

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

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

@example fallback alias

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

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

@param [Symbol] method @param [#call] block

@api public

# 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) click to toggle source

Infer a type identifier from the provided class

@param [#to_s] klass

@return [String]

# File lib/dry/types.rb, line 149
def self.identifier(klass)
  Types::Inflector.underscore(klass).tr("/", ".")
end
included(*) click to toggle source

@api private

# File lib/dry/types.rb, line 73
def self.included(*)
  raise "Import Dry.Types, not Dry::Types"
end
loader() click to toggle source
# 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) click to toggle source

@see Dry.Types

# 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) click to toggle source

Register a new built-in type

@param [String] name @param [Type] type @param [#call,nil] block

@return [Container{String => Nominal}]

@api private

# 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) click to toggle source

Check if a give type is registered

@return [Boolean]

@api private

# File lib/dry/types.rb, line 91
def self.registered?(class_or_identifier)
  container.key?(identifier(class_or_identifier))
end
rule_compiler() click to toggle source

@return [Dry::Logic::RuleCompiler]

@api private

# File lib/dry/types/constraints.rb, line 26
def self.rule_compiler
  @rule_compiler ||= ::Dry::Logic::RuleCompiler.new(::Dry::Logic::Predicates)
end
type_map() click to toggle source

Cached type map

@return [Concurrent::Map]

@api private

# File lib/dry/types.rb, line 158
def self.type_map
  @type_map ||= ::Concurrent::Map.new
end