lib/dry/struct/class_interface.rb in dry-struct-0.7.0 vs lib/dry/struct/class_interface.rb in dry-struct-1.0.0
- old
+ new
@@ -61,12 +61,12 @@
# ruby.details.type #=> 'OO'
#
# @example with a nested array of structs
# class Language < Dry::Struct
# attribute :name, Types::String
- # array :versions, Types::String
- # array :celebrities, Types::Array.of(Dry::Struct) do
+ # attribute :versions, Types::Array.of(Types::String)
+ # attribute :celebrities, Types::Array.of(Dry::Struct) do
# attribute :name, Types::String
# attribute :pseudonym, Types::String
# end
# end
#
@@ -155,12 +155,12 @@
schema schema.schema(new_schema)
keys.each do |key|
next if instance_methods.include?(key)
class_eval(<<-RUBY)
- def #{ key }
- @attributes[#{ key.inspect }]
+ def #{key}
+ @attributes[#{key.inspect}]
end
RUBY
end
@attribute_names = nil
@@ -220,38 +220,47 @@
end
private :check_schema_duplication
# @param [Hash{Symbol => Object},Dry::Struct] attributes
# @raise [Struct::Error] if the given attributes don't conform {#schema}
- def new(attributes = default_attributes)
- if attributes.instance_of?(self)
+ def new(attributes = default_attributes, safe = false)
+ if equal?(attributes.class)
attributes
+ elsif safe
+ load(schema.call_safe(attributes) { |output = attributes| return yield output })
else
- super(schema[attributes])
+ load(schema.call_unsafe(attributes))
end
- rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => error
+ rescue Types::CoercionError => error
raise Struct::Error, "[#{self}.new] #{error}"
end
# @api private
+ def call_safe(input, &block)
+ if input.is_a?(self)
+ input
+ else
+ new(input, true, &block)
+ end
+ end
+
+ # @api private
+ def call_unsafe(input)
+ if input.is_a?(self)
+ input
+ else
+ new(input)
+ end
+ end
+
+ # @api private
def load(attributes)
struct = allocate
struct.send(:initialize, attributes)
struct
end
- # Calls type constructor. The behavior is identical to `.new` but returns
- # the input back if it's a subclass of the struct.
- #
- # @param [Hash{Symbol => Object},Dry::Struct] attributes
- # @return [Dry::Struct]
- def call(attributes = default_attributes)
- return attributes if attributes.is_a?(self)
- new(attributes)
- end
- alias_method :[], :call
-
# @param [#call,nil] constructor
# @param [Hash] _options
# @param [#call,nil] block
# @return [Dry::Struct::Constructor]
def constructor(constructor = nil, **_options, &block)
@@ -272,11 +281,11 @@
# @param [Hash{Symbol => Object},Dry::Struct] input
# @return [Dry::Types::Result]
# @private
def try_struct(input)
if input.is_a?(self)
- Types::Result::Success.new(input)
+ input
else
yield
end
end
@@ -303,13 +312,14 @@
false
end
# @param [Object, Dry::Struct] value
# @return [Boolean]
- def valid?(value)
- self === value
+ def ===(other)
+ other.is_a?(self)
end
+ alias_method :primitive?, :===
# @return [true]
def constrained?
true
end
@@ -320,9 +330,14 @@
end
# @return [false]
def optional?
false
+ end
+
+ # @return [Proc]
+ def to_proc
+ proc { |input| call(input) }
end
# Checks if this {Struct} has the given attribute
#
# @param [Symbol] key Attribute name