module Micro::Attributes

Constants

FetchValueToAssign
MISSING_KEYWORD
MISSING_KEYWORDS
VERSION

Public Class Methods

included(base) click to toggle source
# File lib/micro/attributes.rb, line 13
def self.included(base)
  base.extend(::Micro::Attributes.const_get(:Macros))

  base.class_eval do
    private_class_method :__attributes, :__attribute_reader
    private_class_method :__attribute_assign, :__attributes_groups
    private_class_method :__attributes_required_add, :__attributes_data_to_assign
  end

  def base.inherited(subclass)
    subclass.__attributes_set_after_inherit__(self.__attributes_data__)

    subclass.extend ::Micro::Attributes.const_get('Macros::ForSubclasses'.freeze)
  end
end
with(*names) click to toggle source
# File lib/micro/attributes.rb, line 33
def self.with(*names)
  Features.with(names)
end
with_all_features() click to toggle source
# File lib/micro/attributes.rb, line 37
def self.with_all_features
  Features.all
end
without(*names) click to toggle source
# File lib/micro/attributes.rb, line 29
def self.without(*names)
  Features.without(names)
end

Public Instance Methods

attribute(name) { |value| ... } click to toggle source
# File lib/micro/attributes.rb, line 45
def attribute(name)
  return unless attribute?(name)

  value = public_send(name)

  block_given? ? yield(value) : value
end
attribute!(name, &block) click to toggle source
# File lib/micro/attributes.rb, line 53
def attribute!(name, &block)
  attribute(name) { |name| return block ? block[name] : name }

  raise NameError, __attribute_access_error_message(name)
end
attribute?(name, include_all = false) click to toggle source
# File lib/micro/attributes.rb, line 41
def attribute?(name, include_all = false)
  self.class.attribute?(name, include_all)
end
attributes(*names) click to toggle source
# File lib/micro/attributes.rb, line 65
def attributes(*names)
  return __attributes if names.empty?

  options = names.last.is_a?(Hash) ? names.pop : Kind::Empty::HASH

  names.flatten!

  without_option = Array(options.fetch(:without, Kind::Empty::ARRAY))

  keys = names.empty? ? defined_attributes - without_option.map { |value| __attribute_key(value) } : names - without_option

  data = keys.each_with_object({}) { |key, memo| memo[key] = attribute(key) if attribute?(key) }

  with_option = Array(options.fetch(:with, Kind::Empty::ARRAY))

  unless with_option.empty?
    extra = with_option.each_with_object({}) { |key, memo| memo[__attribute_key(key)] = public_send(key) }

    data.merge!(extra)
  end

  Utils::Hashes.keys_as(options[:keys_as], data)
end
defined_attributes(option = nil) click to toggle source
# File lib/micro/attributes.rb, line 59
def defined_attributes(option = nil)
  return self.class.attributes_by_visibility if option == :by_visibility

  @defined_attributes ||= self.class.attributes
end

Protected Instance Methods

attributes=(arg) click to toggle source
# File lib/micro/attributes.rb, line 91
def attributes=(arg)
  hash = self.class.__attributes_keys_transform__(arg)

  __attributes_missing!(hash)

  __call_before_attributes_assign
  __attributes_assign(hash)
  __call_after_attributes_assign

  __attributes
end

Private Instance Methods

__attribute_access_error_message(name) click to toggle source
# File lib/micro/attributes.rb, line 112
def __attribute_access_error_message(name)
  return "tried to access a private attribute `#{name}" if attribute?(name, true)

  "undefined attribute `#{name}"
end
__attribute_assign(name, init_hash, attribute_data) click to toggle source
# File lib/micro/attributes.rb, line 156
def __attribute_assign(name, init_hash, attribute_data)
  value_to_assign = FetchValueToAssign.(init_hash, init_hash[name], attribute_data)

  ivar_value = instance_variable_set("@#{name}", value_to_assign)

  __attributes[name] = ivar_value if attribute_data[3] == :public
end
__attribute_key(value) click to toggle source
# File lib/micro/attributes.rb, line 118
def __attribute_key(value)
  self.class.__attribute_key_transform__(value)
end
__attributes() click to toggle source
# File lib/micro/attributes.rb, line 122
def __attributes
  @__attributes ||= {}
end
__attributes_assign(hash) click to toggle source
# File lib/micro/attributes.rb, line 148
def __attributes_assign(hash)
  self.class.__attributes_data__.each do |name, attribute_data|
    __attribute_assign(name, hash, attribute_data) if attribute?(name, true)
  end

  __attributes.freeze
end
__attributes_missing!(hash) click to toggle source
# File lib/micro/attributes.rb, line 167
def __attributes_missing!(hash)
  required_keys = self.class.__attributes_required__

  return if required_keys.empty?

  missing_keys = required_keys.map { |name| ":#{name}" if !hash.key?(name) }
  missing_keys.compact!

  return if missing_keys.empty?

  label = missing_keys.size == 1 ? MISSING_KEYWORD : MISSING_KEYWORDS

  raise ArgumentError, "#{label}: #{missing_keys.join(', ')}"
end
__call_after_attributes_assign() click to toggle source
# File lib/micro/attributes.rb, line 106
def __call_after_attributes_assign; end
__call_before_attributes_assign() click to toggle source
# File lib/micro/attributes.rb, line 105
def __call_before_attributes_assign; end
extract_attributes_from(other) click to toggle source
# File lib/micro/attributes.rb, line 108
def extract_attributes_from(other)
  Utils::ExtractAttribute.from(other, keys: defined_attributes)
end