Class: Dry::Interface

Inherits:
Struct
  • Object
show all
Extended by:
ActiveSupport::DescendantsTracker, ActiveSupport::Inflector
Defined in:
lib/dry/interface.rb,
lib/dry/interface/types.rb,
lib/dry/interface/extensions.rb,
lib/dry/interface/interfaces.rb,
lib/dry/interface/extensions/type.rb,
lib/dry/interface/interfaces/value.rb,
lib/dry/interface/interfaces/common.rb,
lib/dry/interface/extensions/default.rb,
lib/dry/interface/interfaces/abstract.rb,
lib/dry/interface/interfaces/concrete.rb

Defined Under Namespace

Modules: Extensions, Interfaces, Types

Class Method Summary collapse

Class Method Details

.alias_fields(_field, aliases: [], **options, &block) ⇒ Object



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

def self.alias_fields(_field, aliases: [], **options, &block)
  if options.key?(:alias)
    aliases << options.delete(:alias)
  end

  block[options]

  aliases.each do |alias_name|
    alias_method alias_name, name
  end
end

.attribute(field, *constrains, **options, &block) ⇒ void

This method returns an undefined value.

Adds attribute name to the struct

Examples:

Add a new attribute

class User < Dry::Struct
  attribute :name, String
end

Add a new attribute with a default value

class User < Dry::Struct
  attribute :name, String, default: "John"
end

Add a new attribute with constraints

class User < Dry::Struct
  attribute :name, String, size: 3..20
end

Add a new attribute with array type

class User < Dry::Struct
  attribute :name, [String]
end

Parameters:

  • name (Symbol)
  • constrains (Array<#to_type>)
  • default (Hash)

    a customizable set of options



110
111
112
113
114
# File 'lib/dry/interface.rb', line 110

def self.attribute(field, *constrains, **options, &block)
  alias_fields(field, **options) do |inner_options|
    super(field, build_type_from(*constrains, **inner_options), &block)
  end
end

.attribute?(field, *constrains, **options, &block) ⇒ Boolean

Optional version of #attribute

Returns:

  • (Boolean)

See Also:

  • #attribute


119
120
121
122
123
# File 'lib/dry/interface.rb', line 119

def self.attribute?(field, *constrains, **options, &block)
  alias_fields(field, **options) do |inner_options|
    super(field, build_type_from(*constrains, **inner_options), &block)
  end
end

.build_type_from(*constrains, **options) ⇒ 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.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/dry/interface.rb', line 157

def self.build_type_from(*constrains, **options)
  unless (type = constrains.map(&:to_type).reduce(:|))
    return build_type_from(Dry::Types["any"], **options)
  end

  if options.key?(:default)
    options.delete(:default).to_default.then do |default_proc|
      return build_type_from(type.default(&default_proc), **options)
    end
  end

  if options.empty?
    return type
  end

  build_type_from(type.constrained(**options))
end

.const_missing(name) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/dry/interface.rb', line 125

def self.const_missing(name)
  case name
  when :Abstract
    return Class.new(self) do
      include Interfaces::Abstract
    end
  when :Concrete
    return Class.new(self) do
      include Interfaces::Concrete
    end
  when :Value
    return Class.new(self) do
      include Interfaces::Value
    end
  end

  super
end

.initializer(owner, &block) ⇒ Object



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

def self.initializer(owner, &block)
  owner.schema owner.schema.constructor(&block)
end

.namedObject



64
65
66
# File 'lib/dry/interface.rb', line 64

def self.named
  format "%<name>s<[%<names>s]>", { name: name, names: direct_descendants.map(&:named).join(" | ") }
end

.newObject



68
69
70
71
72
# File 'lib/dry/interface.rb', line 68

def self.new(...)
  return super unless type

  type.call(...)
end

.otherwise(&block) ⇒ Object



78
79
80
81
82
# File 'lib/dry/interface.rb', line 78

def self.otherwise(&block)
  initializer(self) do |input, type, &error|
    type[input] { block[input, type, &error] }
  end
end

.typeObject



60
61
62
# File 'lib/dry/interface.rb', line 60

def self.type
  direct_descendants.map(&:type).reduce(&:|)
end

.ValueObject



56
57
58
# File 'lib/dry/interface.rb', line 56

def self.Value(...)
  Types.Value(...)
end