HandlerSupport.declare_namespace_method()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
1
# frozen_string_literal: true
2
3
require_relative 'reflection'
4
5
module AMA
6
  module Entity
7
    class Mapper
8
      module Mixin
9
        # This module provides Type and Attribute classes with shortcut
10
        # handler :name, :method method to register handlers
11
        module HandlerSupport
12
          class << self
13
            def included(klass)
14
              declare_namespace_method(klass)
15
              declare_handler_method(klass)
16
            end
17
18
            def declare_namespace_method(klass)
19
              klass.define_singleton_method(:handler_namespace) do |namespace|
20
                @handler_namespace = namespace
21
              end
22
            end
23
24
            def declare_handler_method(klass)
25
              processor = self
26
              klass.define_singleton_method(:handler) do |key, method|
27
                handler_name = key.capitalize
28
                handler_class = @handler_namespace.const_get(handler_name)
29
                processor.declare_handler_getter(klass, key, handler_class)
30
                processor.declare_handler_setter(klass, key, handler_class)
31
                processor.declare_handler_block_setter(klass, key, method)
32
              end
33
            end
34
35
            def declare_handler_getter(klass, handler_key, handler_class)
36
              instance = handler_class::INSTANCE
37
              klass.instance_eval do
38
                define_method(handler_key) do
39
                  instance_variable_get("@#{handler_key}") || instance
40
                end
41
              end
42
            end
43
44
            def declare_handler_setter(klass, handler_key, handler_class)
45
              klass.instance_eval do
46
                define_method("#{handler_key}=") do |handler|
47
                  unless handler.class == handler_class
48
                    handler = handler_class.wrap(handler)
49
                  end
50
                  instance_variable_set("@#{handler_key}", handler)
51
                  self
52
                end
53
              end
54
            end
55
56
            def declare_handler_block_setter(klass, handler_key, method)
57
              klass.instance_eval do
58
                include Mixin::Reflection
59
                define_method("#{handler_key}_block") do |&block|
60
                  send("#{handler_key}=", method_object(method, &block))
61
                end
62
              end
63
            end
64
          end
65
        end
66
      end
67
    end
68
  end
69
end
70