class ConfigX::Interface::Builder

Public Class Methods

new(config_interface, owner_interface, namespace = [], store_map = {}) click to toggle source
# File lib/config_x/interface/builder.rb, line 4
def initialize(config_interface, owner_interface, namespace = [], store_map = {})
  @config_interface = config_interface
  @owner_interface = owner_interface
  @namespace = namespace
  @store_map = store_map
end

Public Instance Methods

attr(name, opts = {}, &block) click to toggle source
# File lib/config_x/interface/builder.rb, line 16
def attr(name, opts = {}, &block)
  name = name.to_s
  validate_attr_name(name)

  if block
    define_nested_attr_interface(name, opts, &block)
  else
    define_attr_interface(name, opts, &block)
  end
end
build(&block) click to toggle source
# File lib/config_x/interface/builder.rb, line 11
def build(&block)
  instance_exec(&block)
  @store_map
end

Private Instance Methods

config_prefixed_namespaced_name(name) click to toggle source
# File lib/config_x/interface/builder.rb, line 134
def config_prefixed_namespaced_name(name)
  ([CONFIG_NAMESPACE] + namespace_for(name)).join(NAMESPACE_SEPARATOR)
end
define_attr_interface(name, opts) click to toggle source
# File lib/config_x/interface/builder.rb, line 29
def define_attr_interface(name, opts)
  config_prefixed_namespaced_name = config_prefixed_namespaced_name(name)
  @store_map[name] = config_prefixed_namespaced_name

  define_getter(
    @config_interface,
    name,
    @namespace,
    config_prefixed_namespaced_name,
    opts
  )

  define_setter(
    @config_interface,
    name,
    @namespace,
    config_prefixed_namespaced_name
  )

  return unless opts[:accessor]

  define_getter(
    @owner_interface,
    name,
    @namespace,
    namespaced_name(name, '_'),
    opts
  )

  define_setter(
    @owner_interface,
    name,
    @namespace,
    namespaced_name(name, '_')
  )
end
define_delegator(target, method_name, namespace) click to toggle source
# File lib/config_x/interface/builder.rb, line 146
def define_delegator(target, method_name, namespace)
  target.send :define_method, method_name do
    NamespaceDelegator.new(self, namespace)
  end
end
define_getter(target, variable_name, namespace, method_name, opts = {}) click to toggle source
# File lib/config_x/interface/builder.rb, line 96
def define_getter(target, variable_name, namespace, method_name, opts = {})
  proc_name = "#{variable_name}#{PROC_SEPARATOR}proc"

  target.send :define_method, method_name do |&block|
    namespaced_config = config_store

    if namespace.any?
      namespaced_config = namespace.inject(config_store) do |acc, key|
        acc[key] ||= {}
      end
    end

    if block
      namespaced_config[proc_name] = block
    elsif namespaced_config[variable_name]
      namespaced_config[variable_name]
    elsif value = namespaced_config[proc_name] || opts[:default]
      return value if opts[:eval] == false
      value = evaluate_config_proc_or_value(value, instance_exec: opts[:instance_exec])
      namespaced_config[variable_name] = value if opts[:memoize]
      value
    end
  end
end
define_nested_attr_interface(name, opts, &block) click to toggle source
# File lib/config_x/interface/builder.rb, line 66
def define_nested_attr_interface(name, opts, &block)
  config_prefixed_namespaced_name = config_prefixed_namespaced_name(name)

  Builder.new(
    @config_interface,
    @owner_interface,
    @namespace + [name],
    @store_map[name] ||= {}
  ).build(&block)

  define_delegator(
    @config_interface,
    config_prefixed_namespaced_name,
    @namespace + [name]
  )

  return unless opts[:accessor]

  define_delegator(
    @owner_interface,
    namespaced_name(name),
    @namespace + [name]
  )
end
define_setter(target, variable_name, namespace, method_name = variable_name) click to toggle source
# File lib/config_x/interface/builder.rb, line 121
def define_setter(target, variable_name, namespace, method_name = variable_name)
  target.send :define_method, "#{method_name}=" do |value|
    namespaced_config = config_store

    if namespace.any?
      namespaced_config = namespace.inject(config_store) do |acc, key|
        acc[key] ||= {}
      end
    end
    namespaced_config[variable_name] = value
  end
end
namespace_for(name) click to toggle source
# File lib/config_x/interface/builder.rb, line 142
def namespace_for(name)
  (@namespace + [name]).compact
end
namespaced_name(name, separator = NAMESPACE_SEPARATOR) click to toggle source
# File lib/config_x/interface/builder.rb, line 138
def namespaced_name(name, separator = NAMESPACE_SEPARATOR)
  namespace_for(name).join(separator)
end
validate_attr_name(name) click to toggle source
# File lib/config_x/interface/builder.rb, line 91
def validate_attr_name(name)
  return if name =~ /\A[0-9a-zA-z_]+\z/
  raise StandardError, "Attribute name #{name} is not allowed. Only [0-9a-zA-z_]+"
end