Sha256: a64bef6c19d48d00836f056082d5283c752e232e7a0de5676781916f7190a737

Contents?: true

Size: 1.48 KB

Versions: 1

Compression:

Stored size: 1.48 KB

Contents

# frozen_string_literal: true

module Taksi
  module Widgets
    class ContentKey
      attr_reader :skeleton, :key, :value, :parent

      def initialize(skeleton, key, *args, parent: nil, &block)
        @skeleton = skeleton
        @key = key.to_sym
        @parent = parent

        @value = args.shift.new(skeleton, full_key, *args) if args.size.positive?
        @nested_keys = []

        instance_exec(&block) if block_given?
        @defined = true
      end

      def full_key
        return key if parent.nil? || parent.root?

        "#{parent.full_key}.#{key}"
      end

      def fetch_from(data)
        return data[key] if parent.nil? || parent.root?

        parent.fetch_from(data)[key]
      rescue NoMethodError
        raise NameError, "Couldn't fetch #{key.inspect} from data: #{data.inspect}"
      end

      def as_json
        return {key => @nested_keys.map(&:as_json).inject({}, &:merge)} if nested?

        {key => value.as_json}
      end

      def keys
        Enumerator.new do |yielder|
          @nested_keys.each do |key|
            if key.nested?
              key.keys.each(&yielder)
            else
              yielder << key
            end
          end
        end
      end

      def nested?
        @value.nil?
      end

      def root?
        @parent.nil?
      end

      def method_missing(name, *args, &block)
        return super if @defined

        @nested_keys << self.class.new(skeleton, name, *args, parent: self, &block)
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
taksi-0.1.0 lib/taksi/widgets/content_key.rb