Sha256: e76c7bef5251e5b78d8db48ad226c89c1da47c79d3b3956ab5ce21125d5487bd

Contents?: true

Size: 1.85 KB

Versions: 1

Compression:

Stored size: 1.85 KB

Contents

module Dry
  module Types
    class Struct
      class << self
        attr_reader :constructor
      end

      def self.inherited(klass)
        super

        klass.instance_variable_set('@equalizer', Equalizer.new)
        klass.send(:include, klass.equalizer)

        unless klass == Value
          klass.instance_variable_set('@constructor', Types['coercible.hash'])
          Types.register_class(klass)
        end
      end

      def self.equalizer
        @equalizer
      end

      def self.attribute(name, type)
        attributes(name => type)
      end

      def self.attributes(new_schema)
        prev_schema = schema

        @schema = prev_schema.merge(new_schema)
        @constructor = Types['coercible.hash'].public_send(constructor_type, schema)

        attr_reader(*(new_schema.keys - prev_schema.keys))
        equalizer.instance_variable_get('@keys').concat(schema.keys).uniq!

        self
      end

      def self.constructor_type(type = :strict)
        @constructor_type ||= type
      end

      def self.schema
        super_schema = superclass.respond_to?(:schema) ? superclass.schema : {}
        super_schema.merge(@schema || {})
      end

      def self.new(attributes = {})
        if attributes.is_a?(self)
          attributes
        else
          super(constructor[attributes])
        end
      rescue SchemaError, SchemaKeyError => e
        raise StructError, "[#{self}.new] #{e.message}"
      end

      def initialize(attributes)
        attributes.each { |key, value| instance_variable_set("@#{key}", value) }
      end

      def [](name)
        public_send(name)
      end

      def to_hash
        self.class.schema.keys.each_with_object({}) { |key, result|
          value = self[key]
          result[key] = value.respond_to?(:to_hash) ? value.to_hash : value
        }
      end
      alias_method :to_h, :to_hash
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
dry-types-0.7.0 lib/dry/types/struct.rb