Module: Dry::Types

Extended by:
Configurable, Core::Extensions
Includes:
Core::Constants
Defined in:
lib/dry/types.rb,
lib/dry/types/any.rb,
lib/dry/types/sum.rb,
lib/dry/types/core.rb,
lib/dry/types/enum.rb,
lib/dry/types/form.rb,
lib/dry/types/hash.rb,
lib/dry/types/json.rb,
lib/dry/types/safe.rb,
lib/dry/types/type.rb,
lib/dry/types/array.rb,
lib/dry/types/errors.rb,
lib/dry/types/result.rb,
lib/dry/types/builder.rb,
lib/dry/types/default.rb,
lib/dry/types/options.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/definition.rb,
lib/dry/types/constrained.rb,
lib/dry/types/constraints.rb,
lib/dry/types/constructor.rb,
lib/dry/types/hash/schema.rb,
lib/dry/types/array/member.rb,
lib/dry/types/fn_container.rb,
lib/dry/types/coercions/form.rb,
lib/dry/types/coercions/json.rb,
lib/dry/types/builder_methods.rb,
lib/dry/types/extensions/maybe.rb,
lib/dry/types/constrained/coercible.rb

Overview

Returns:

  • (Module)

Defined Under Namespace

Modules: Builder, BuilderMethods, Coercions, Decorator, Options, Type Classes: Array, Compiler, Constrained, ConstraintError, Constructor, Container, Default, Definition, Enum, FnContainer, Hash, Maybe, MissingKeyError, Result, Safe, SchemaError, Sum, UnknownKeysError

Constant Summary collapse

TYPE_SPEC_REGEX =
%r[(.+)<(.+)>].freeze
Any =
Class.new(Definition) do
  def initialize(**options)
    super(::Object, options)
  end

  # @return [String]
  def name
    'Any'
  end

  # @param [Object] any input is valid
  # @return [true]
  def valid?(_)
    true
  end

  # @param [Hash] new_options
  # @return [Type]
  def with(new_options)
    self.class.new(**options, meta: @meta, **new_options)
  end
end.new
COERCIBLE =
{
  string: String,
  int: Integer,
  float: Float,
  decimal: BigDecimal,
  array: ::Array,
  hash: ::Hash
}.freeze
NON_COERCIBLE =
{
  nil: NilClass,
  symbol: Symbol,
  class: Class,
  true: TrueClass,
  false: FalseClass,
  date: Date,
  date_time: DateTime,
  time: Time
}.freeze
ALL_PRIMITIVES =
COERCIBLE.merge(NON_COERCIBLE).freeze
NON_NIL =
ALL_PRIMITIVES.reject { |name, _| name == :nil }.freeze
SchemaKeyError =
Class.new(KeyError)
VERSION =
'0.12.1'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#namespaceContainer{String => Definition} (readonly)

Returns:



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

setting :namespace, self

Class Method Details

.[](name) ⇒ Type, Class

Parameters:

  • name (String, Class)

Returns:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/dry/types.rb', line 81

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
      type_name = identifier(name)

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

.const_missing(const) ⇒ Object (private)

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.



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/dry/types.rb', line 143

def self.const_missing(const)
  underscored = Inflecto.underscore(const)

  if type_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["strict.int"] '\
          'or generate a module with types using Dry::Types.module'
  else
    super
  end
end

.containerContainer{String => Definition}

Returns:



53
54
55
# File 'lib/dry/types.rb', line 53

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

.define_constants(namespace, identifiers) ⇒ <Definition>

Parameters:

  • namespace (Module)
  • identifiers (<String>)

Returns:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/dry/types.rb', line 108

def self.define_constants(namespace, identifiers)
  names = identifiers.map do |id|
    parts = id.split('.')
    [Inflecto.camelize(parts.pop), parts.map(&Inflecto.method(:camelize))]
  end

  names.map do |(klass, parts)|
    mod = parts.reduce(namespace) do |a, e|
      a.constants.include?(e.to_sym) ? a.const_get(e) : a.const_set(e, Module.new)
    end

    mod.const_set(klass, self[identifier((parts + [klass]).join('::'))])
  end
end

.finalizeObject

Deprecated.

Include module instead



44
45
46
47
48
49
50
# File 'lib/dry/types.rb', line 44

def self.finalize
  warn 'Dry::Types.finalize and configuring namespace is deprecated. Just'\
   ' do `include Dry::Types.module` in places where you want to have access'\
   ' to built-in types'

  define_constants(config.namespace, type_keys)
end

.identifier(klass) ⇒ String

Parameters:

  • klass (#to_s)

Returns:

  • (String)


125
126
127
# File 'lib/dry/types.rb', line 125

def self.identifier(klass)
  Inflecto.underscore(klass).tr('/', '.')
end

.moduleObject



36
37
38
39
40
41
# File 'lib/dry/types.rb', line 36

def self.module
  namespace = Module.new
  define_constants(namespace, type_keys)
  namespace.extend(BuilderMethods)
  namespace
end

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

Parameters:

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

Returns:



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

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

.register_class(klass, meth = :new) ⇒ Container{String => Definition}

Registers given +klass+ in #container using +meth+ constructor

Parameters:

  • klass (Class)
  • meth (Symbol) (defaults to: :new)

Returns:



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

def self.register_class(klass, meth = :new)
  type = Definition.new(klass).constructor(klass.method(meth))
  container.register(identifier(klass), type)
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.

Returns:

  • (Boolean)


58
59
60
# File 'lib/dry/types.rb', line 58

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

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

Parameters:

Returns:

  • (Dry::Logic::Rule)


9
10
11
12
13
# File 'lib/dry/types/constraints.rb', line 9

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

.rule_compilerDry::Logic::RuleCompiler

Returns:

  • (Dry::Logic::RuleCompiler)


16
17
18
# File 'lib/dry/types/constraints.rb', line 16

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

.type_keys<String>

List of type keys defined in container

Returns:

  • (<String>)


136
137
138
# File 'lib/dry/types.rb', line 136

def self.type_keys
  container.keys
end

.type_mapConcurrent::Map

Returns:

  • (Concurrent::Map)


130
131
132
# File 'lib/dry/types.rb', line 130

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