Sha256: 0954ee6fb84f74457992e3dfa76b8e77ab3096786cf1b67d53197c1d45fc0834

Contents?: true

Size: 1.65 KB

Versions: 10

Compression:

Stored size: 1.65 KB

Contents

module Formalist
  class Definition
    DuplicateElementError = Class.new(StandardError)

    attr_reader :form
    attr_reader :config
    attr_reader :elements

    def initialize(form, config, &block)
      @form = form
      @config = config
      @elements = []

      instance_eval(&block) if block
    end

    def with(**new_options, &block)
      new_config = new_options.each_with_object(config.dup) { |(key, value), config|
        config.send :"#{key}=", value
      }

      self.class.new(form, new_config, &block)
    end

    def method_missing(name, *args, &block)
      if element_type?(name)
        add_element(name, *args, &block)
      elsif form.respond_to?(name, include_private = true)
        form.send(name, *args, &block)
      else
        super
      end
    end

    private

    def respond_to_missing?(name, _include_private = false)
      element_type?(name) || form.respond_to?(name, _include_private = true) || super
    end

    def element_type?(type)
      config.elements_container.key?(type)
    end

    def add_element(type, *args, &block)
      element_name = args.shift unless args.first.is_a?(Hash)
      element_attrs = args.last.is_a?(Hash) ? args.last : {}

      if element_name && elements.any? { |element| element.name == element_name }
        raise DuplicateElementError, "element +#{element_name}+ is already defined in this context"
      end

      element_class = config.elements_container[type]
      element_children = with(&block).elements

      element = element_class.build(
        name: element_name,
        attributes: element_attrs,
        children: element_children,
      )

      elements << element
    end
  end
end

Version data entries

10 entries across 10 versions & 1 rubygems

Version Path
formalist-0.9.0 lib/formalist/definition.rb
formalist-0.8.0 lib/formalist/definition.rb
formalist-0.7.0 lib/formalist/definition.rb
formalist-0.6.0 lib/formalist/definition.rb
formalist-0.5.4 lib/formalist/definition.rb
formalist-0.5.3 lib/formalist/definition.rb
formalist-0.5.2 lib/formalist/definition.rb
formalist-0.5.1 lib/formalist/definition.rb
formalist-0.5.0 lib/formalist/definition.rb
formalist-0.4.2 lib/formalist/definition.rb