Class: ConfigMapper::ConfigStruct

Inherits:
Object
  • Object
show all
Defined in:
lib/config_mapper/config_struct.rb

Overview

A set of configurable attributes.

Defined Under Namespace

Classes: NoValueProvided

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfigStruct

Returns a new instance of ConfigStruct.



107
108
109
110
111
# File 'lib/config_mapper/config_struct.rb', line 107

def initialize
  self.class.attribute_initializers.each do |name, initializer|
    instance_variable_set("@#{name}", initializer.call)
  end
end

Class Method Details

.attribute(name, options = {}) { ... } ⇒ Object

Defines reader and writer methods for the specified attribute.

A :default value may be specified; otherwise, the attribute is considered mandatory.

If a block is provided, it will invoked in the writer-method to validate the argument.

Parameters:

  • name (Symbol)

    attribute name

Yields:

  • type-coercion block



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/config_mapper/config_struct.rb', line 24

def attribute(name, options = {})
  name = name.to_sym
  required = true
  default_value = nil
  if options.key?(:default)
    default_value = options.fetch(:default).freeze
    required = false if default_value.nil?
  end
  attribute_initializers[name] = proc { default_value }
  required_attributes << name if required
  attr_reader(name)
  define_method("#{name}=") do |value|
    if value.nil?
      raise NoValueProvided if required
    else
      value = yield(value) if block_given?
    end
    instance_variable_set("@#{name}", value)
  end
end

.attribute_initializersObject



93
94
95
# File 'lib/config_mapper/config_struct.rb', line 93

def attribute_initializers
  @attribute_initializers ||= {}
end

.component(name, options = {}, &block) ⇒ Object

Defines a sub-component.

If a block is be provided, it will be ‘class_eval`ed to define the sub-components class.

Parameters:

  • name (Symbol)

    component name



54
55
56
57
58
59
60
61
62
# File 'lib/config_mapper/config_struct.rb', line 54

def component(name, options = {}, &block)
  name = name.to_sym
  declared_components << name
  type = options.fetch(:type, ConfigStruct)
  type = Class.new(type, &block) if block
  type = type.method(:new) if type.respond_to?(:new)
  attribute_initializers[name] = type
  attr_reader name
end

.component_dict(name, options = {}, &block) ⇒ Object

Defines an associative array of sub-components.

If a block is be provided, it will be ‘class_eval`ed to define the sub-components class.

Parameters:

  • name (Symbol)

    dictionary attribute name



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/config_mapper/config_struct.rb', line 75

def component_dict(name, options = {}, &block)
  name = name.to_sym
  declared_component_dicts << name
  type = options.fetch(:type, ConfigStruct)
  type = Class.new(type, &block) if block
  type = type.method(:new) if type.respond_to?(:new)
  key_type = options[:key_type]
  key_type = key_type.method(:new) if key_type.respond_to?(:new)
  attribute_initializers[name] = lambda do
    ConfigDict.new(type, key_type)
  end
  attr_reader name
end

.declared_component_dictsObject



101
102
103
# File 'lib/config_mapper/config_struct.rb', line 101

def declared_component_dicts
  @declared_component_dicts ||= []
end

.declared_componentsObject



97
98
99
# File 'lib/config_mapper/config_struct.rb', line 97

def declared_components
  @declared_components ||= []
end

.required_attributesObject



89
90
91
# File 'lib/config_mapper/config_struct.rb', line 89

def required_attributes
  @required_attributes ||= []
end

Instance Method Details

#config_errorsObject



117
118
119
# File 'lib/config_mapper/config_struct.rb', line 117

def config_errors
  immediate_config_errors.merge(component_config_errors)
end

#configure_with(attribute_values) ⇒ Hash

Configure with data.

Parameters:

  • attribute_values (Hash)

    attribute values

Returns:

  • (Hash)

    errors encountered, keyed by attribute path



126
127
128
129
# File 'lib/config_mapper/config_struct.rb', line 126

def configure_with(attribute_values)
  errors = ConfigMapper.configure_with(attribute_values, self)
  config_errors.merge(errors)
end

#immediate_config_errorsObject



113
114
115
# File 'lib/config_mapper/config_struct.rb', line 113

def immediate_config_errors
  missing_required_attribute_errors
end

#to_hHash

Return the configuration as a Hash.

Returns:

  • (Hash)

    serializable config data



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/config_mapper/config_struct.rb', line 135

def to_h
  {}.tap do |result|
    self.class.attribute_initializers.keys.each do |attr_name|
      value = send(attr_name)
      if value && value.respond_to?(:to_h) && !value.is_a?(Array)
        value = value.to_h
      end
      result[attr_name.to_s] = value
    end
  end
end