Sha256: 6df095ed943b8080562a91e4f7303f33a7e015e9a5ba0084969d077d839cc9b7

Contents?: true

Size: 1.65 KB

Versions: 2

Compression:

Stored size: 1.65 KB

Contents

# Base structure for models describing parts of requests and responses
#
# The initializer accepts a hash with symbol/string keys,
# from which it takes and validates necessary options.
#
# The method [#to_h] converts nested data to hash
# with symbolic keys at any level of nesting.
#
class Evil::Client
  class Model
    class << self
      include Dry::Initializer::Mixin

      def new(value)
        return value if value.is_a? self
        value = value.to_h.each_with_object({}) do |(key, val), obj|
          obj[key.to_sym] = val
        end
        super value
      end
      alias_method :call, :new
      alias_method :[], :new

      def attributes
        @attributes ||= []
      end

      def option(name, type = nil, **opts)
        super.tap { attributes << name.to_sym }
      end
      alias_method :attribute, :option
      alias_method :param, :option

      private

      def inherited(klass)
        super
        klass.instance_variable_set :@attributes, attributes.dup
      end
    end

    def ==(other)
      other.respond_to?(:to_h) ? to_h == other.to_h : false
    end

    def to_h
      self.class.attributes.each_with_object({}) do |key, hash|
        val = send(key)
        hash[key] = hashify(val) unless val == Dry::Initializer::UNDEFINED
      end
    end
    alias_method :[], :send

    private

    def hashify(value)
      if value.is_a? Evil::Client::Model
        value.to_h
      elsif value.respond_to? :to_hash
        value.to_hash
             .each_with_object({}) { |(key, val), obj| obj[key] = hashify(val) }
      elsif value.is_a? Enumerable
        value.map { |val| hashify(val) }
      else
        value
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
evil-client-0.2.3 lib/evil/client/model.rb
evil-client-0.2.2 lib/evil/client/model.rb