class SleepingKingStudios::Tools::Toolbox::Configuration

Abstract base class for defining configuration objects.

Constants

DEFAULT_OPTION

Attributes

data[R]
root_namespace[RW]

Public Class Methods

new(data = nil) { |singleton_class| ... } click to toggle source

@param data [Hash, Object] The data source used to populate configuration

values. Can be a Hash or a data object. If the data source is nil, or no
data source is given, values will be set to their respective defaults.

@yieldparam [Class] The singleton class of the new configuration object.

# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 125
def initialize(data = nil)
  @data           = convert_data_to_struct(data)
  @root_namespace = self

  return unless block_given?

  SleepingKingStudios::Tools::CoreTools
    .deprecate('Configuration#initialize with a block')

  yield(singleton_class)
end

Public Instance Methods

[](key) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 137
def [](key)
  send(key) if respond_to?(key)
end
[]=(key, value) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 141
def []=(key, value)
  send(:"#{key}=", value) if respond_to?(key)
end
dig(*keys) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 145
def dig(*keys)
  keys.reduce(self) do |config, key|
    value = config[key]

    return value if value.nil?

    value
  end
end
fetch(key, default = DEFAULT_OPTION) { |key| ... } click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 155
def fetch(key, default = DEFAULT_OPTION)
  return send(key) if respond_to?(key)

  return default unless default == DEFAULT_OPTION

  return yield(key) if block_given?

  raise KeyError, "key not found: #{key.inspect}"
end

Private Instance Methods

blank_value?(value) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 173
def blank_value?(value)
  value.nil? || (value.respond_to?(:empty?) && value.empty?)
end
convert_data_to_struct(data) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 177
def convert_data_to_struct(data)
  return data unless data.is_a?(Hash)

  return Object.new if data.empty?

  obj = Struct.new(*data.keys).new

  data.each do |key, value|
    val = value.is_a?(Hash) ? convert_data_to_struct(value) : value

    obj.send :"#{key}=", val
  end

  obj
end
evaluate_default(default) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 193
def evaluate_default(default)
  return default unless default.is_a?(Proc)

  root_namespace.instance_exec(&default)
end
get_default_value(options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 199
def get_default_value(options)
  value = evaluate_default(options[:default])

  validate_value value, options

  value
end
get_method_value(name, options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 207
def get_method_value(name, options)
  value = data.send(name)

  if value.nil? && options[:default] != DEFAULT_OPTION
    value = evaluate_default(options[:default])
  end

  validate_value(value, options)

  value
end
get_value(name, options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 219
def get_value(name, options)
  if data.respond_to?(name)
    get_method_value(name, options)
  elsif instance_variable_defined?(:"@#{name}")
    instance_variable_get(:"@#{name}")
  elsif options[:default] != DEFAULT_OPTION
    get_default_value(options)
  else
    validate_value(nil, options)

    nil
  end
end
initialize_namespace(namespace_name, namespace_class, &block) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 233
def initialize_namespace(namespace_name, namespace_class, &block)
  data   = get_value(namespace_name, default: Object.new)
  config = namespace_class.new(data)

  config.root_namespace = root_namespace || self

  instance_variable_set(:"@#{namespace_name}", config)

  block.call(config) if block_given?

  config
end
invalid_value_message(value, options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 246
def invalid_value_message(value, options)
  array_tools   = ::SleepingKingStudios::Tools::ArrayTools
  valid_options =
    array_tools
    .humanize_list(
      options[:enum].map(&:inspect),
      last_separator: ' or '
    )

  "expected option to be #{valid_options}, but was #{value.inspect}"
end
set_value(name, value, options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 258
def set_value(name, value, options)
  writer_name = :"#{name}="

  validate_value value, options

  if data.respond_to?(writer_name)
    data.send(writer_name, value)
  else
    # Store values locally if data source is immutable.
    instance_variable_set(:"@#{name}", value)
  end
end
validate_value(value, options) click to toggle source
# File lib/sleeping_king_studios/tools/toolbox/configuration.rb, line 271
def validate_value(value, options)
  return if blank_value?(value) && options[:allow_nil]

  return unless options[:enum] && !options[:enum].include?(value)

  raise invalid_value_message(value, options)
end