Completed
Push — dev ( 73864e...ffd8f7 )
by Fike
38s
created

Type.parameter!   A

Complexity

Conditions 2

Size

Total Lines 4

Duplication

Lines 4
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 4
loc 4
rs 10
cc 2
1
# frozen_string_literal: true
2
3
# rubocop:disable Lint/UnusedMethodArgument
4
5
require_relative 'exception/compliance_error'
6
7
module AMA
8
  module Entity
9
    class Mapper
10
      # Base abstract class for all other types
11
      class Type
12
        # @return [Hash{Symbol, AMA::Entity::Mapper::Type::Attribute}]
13
        def attributes
14
          compliance_error("Type #{self} doesn't support attributes")
15
        end
16
17
        # @return [Hash{Symbol, AMA::Entity::Mapper::Type}]
18
        def parameters
19
          compliance_error("Type #{self} doesn't support parameters")
20
        end
21
22
        def supports_parameters?
23
          false
24
        end
25
26
        def supports_attributes?
27
          false
28
        end
29
30
        # @param [AMA::Entity::Mapper::Type] parameter
31
        # @param [AMA::Entity::Mapper::Type] substitution
32
        def resolve_parameter(parameter, substitution)
33
          if supports_parameters?
34
            parameters.each do |id, bound_parameter|
35
              parameters[id] = substitution if bound_parameter == parameter
36
            end
37
          end
38
          return unless supports_attributes?
39
          attributes.values.each do |attribute|
40
            attribute.types = attribute.types.map do |type|
41
              next substitution if type == parameter
42
              type.resolve_parameter(parameter, substitution)
43
              type
44
            end
45
          end
46
        end
47
48
        def resolve(parameters)
49
          parameters.each do |parameter, substitution|
50
            resolve_parameter(parameter, substitution)
51
          end
52
        end
53
54
        # @return [TrueClass, FalseClass]
55
        def resolved?
56
          if supports_parameters? && !parameters.values.all?(&:resolved?)
57
            return false
58
          end
59
          return true unless supports_attributes?
60
          attributes.values.flat_map(&:types).all?(&:resolved?)
61
        end
62
63
        # @param [AMA::Entity::Mapper::Type] parameter
64
        # @return [TrueClass, FalseClass]
65
        def parameter_of?(parameter)
66
          parameters.values.include?(parameter)
67
        end
68
69
        # @param [AMA::Entity::Mapper::Type] parameter
70
        def parameter_of!(parameter)
71
          return if parameter_of?(parameter)
72
          message = "Type #{self} doesn't have parameter with type #{parameter}"
73
          compliance_error(message)
74
        end
75
76
        # @param [Symbol] id
77
        # @return [TrueClass, FalseClass]
78
        def parameter?(id)
79
          parameters.key?(id)
80
        end
81
82
        # @param [Symbol] id
83 View Code Duplication
        def parameter!(id)
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
84
          return if parameter?(id)
85
          compliance_error("Type #{self} doesn't have parameter #{id}")
86
        end
87
88 View Code Duplication
        def absent_parameter!(id)
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
89
          return unless parameter?(id)
90
          compliance_error("Type #{self} has defined parameter #{id}")
91
        end
92
93
        def hash
94
          abstract_method
95
        end
96
97
        def eql?(other)
98
          abstract_method
99
        end
100
101
        def ==(other)
102
          eql?(other)
103
        end
104
105
        def to_s
106
          abstract_method
107
        end
108
109
        def validate!
110
          # noop
111
        end
112
113
        protected
114
115
        def compliance_error(message)
116
          raise ::AMA::Entity::Mapper::Exception::ComplianceError, message
117
        end
118
119
        private
120
121
        def abstract_method
122
          message = "Abstract method #{__callee__} hasn't been implemented " \
123
            "in class #{self.class}"
124
          raise message
125
        end
126
      end
127
    end
128
  end
129
end
130