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