Class: ReeMapper::MapperFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mapper) ⇒ MapperFactory

Returns a new instance of MapperFactory.



147
148
149
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 147

def initialize(mapper)
  @mapper = mapper
end

Class Attribute Details

.strategiesObject (readonly)

Returns the value of attribute strategies.



5
6
7
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 5

def strategies
  @strategies
end

.typesObject (readonly)

Returns the value of attribute types.



5
6
7
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 5

def types
  @types
end

.wrappersObject (readonly)

Returns the value of attribute wrappers.



5
6
7
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 5

def wrappers
  @wrappers
end

Class Method Details

.call(register_as: nil, &blk) ⇒ Object



142
143
144
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 142

def self.call(register_as: nil, &blk)
  ReeMapper::MapperFactoryProxy.new(self, register_as: register_as, &blk)
end

.find_strategy(strategy_method) ⇒ Object



9
10
11
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 9

def self.find_strategy(strategy_method)
  strategies.detect { _1.method == strategy_method }
end

.register_mapper(name, type) ⇒ Object

Raises:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 22

def self.register_mapper(name, type)
  raise ArgumentError, "mapper registration name should not end with `?`" if name.to_s.end_with?('?')

  defined_strategy_method = types[name]&.flat_map(&:strategy_methods)&.detect { type.find_strategy(_1) }
  raise ArgumentError, "type :#{name} with `#{defined_strategy_method}` strategy already registered" if defined_strategy_method
  raise ArgumentError, "method :#{name} already defined" if !types.key?(name) && method_defined?(name)

  type = type.dup
  type.name = name
  type.freeze
  types[name] ||= []
  types[name] << type

  class_eval("    def \#{name}(field_name = nil, optional: false, **opts)\n      raise ReeMapper::Error, \"invalid DSL usage\" unless @mapper\n      raise ArgumentError, \"wrapped item can't be optional\" if field_name.nil? && optional\n\n      type = self.class.types.fetch(:\#{name}).detect { (@mapper.strategy_methods - _1.strategy_methods).empty? }\n\n      unless type\n        raise ReeMapper::UnsupportedTypeError, \"type :\#{name} should implement `\\\#{@mapper.strategy_methods.join(', ')}`\"\n      end\n\n      field = ReeMapper::Field.new(\n        type,\n        field_name,\n        optional: optional,\n        **opts,\n        location: caller_locations&.first&.to_s\n      )\n\n      return field unless field_name\n\n      @mapper.add_field(field)\n    end\n\n    def \#{name}?(field_name, **opts)\n      \#{name}(field_name, optional: true, **opts)\n    end\n  RUBY\n\n  self\nend\n", __FILE__, __LINE__ + 1)

.register_type(name, object_type, strategies: self.strategies) ⇒ Object



14
15
16
17
18
19
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 14

def self.register_type(name, object_type, strategies: self.strategies)
  register_mapper(
    name,
    ReeMapper::Mapper.build(strategies, object_type)
  )
end

.register_wrapper(name, wrapper) ⇒ Object

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 68

def self.register_wrapper(name, wrapper)
  raise ArgumentError, "wrapper registration name should not end with `?`" if name.to_s.end_with?('?')
  raise ArgumentError, "method :#{name} already defined" if !wrappers.key?(name) && method_defined?(name)

  wrappers[name] ||= []
  wrappers[name] << wrapper

  class_eval("    contract(\n      Nilor[Symbol, ReeMapper::Field],\n      Nilor[ReeMapper::Field],\n      Kwargs[optional: Bool, dto: Nilor[Class]],\n      Ksplat[RestKeys => Any],\n      Optblock => Nilor[ReeMapper::Field]\n    ).throws(ReeMapper::Error, ArgumentError, ReeMapper::UnsupportedTypeError)\n    def \#{name}(field_name = nil, subject = nil, optional: false, dto: nil, **opts, &blk)\n      raise ReeMapper::Error, \"invalid DSL usage\" unless @mapper\n      raise ArgumentError, 'wrapped type does not permit :dto without :block' if dto && !blk\n\n      if field_name.is_a?(ReeMapper::Field)\n        raise ArgumentError, \"field_name should be a Symbol\" if subject\n\n        subject = field_name\n        field_name = nil\n      end\n\n      raise ArgumentError, \"wrapped item can't be optional\" if field_name.nil? && optional\n      raise ArgumentError, \"wrapped type should use either :subject or :block\" if subject && blk || !subject && !blk\n\n      if blk\n        subject = ReeMapper::Field.new(\n          hash_from_blk(dto: dto, &blk),\n          location: caller_locations&.first&.to_s,\n        )\n      end\n\n      wrapper = self.class.wrappers.fetch(:\#{name}).detect do |wrapper|\n        @mapper.strategy_methods.all? { wrapper.method_defined?(_1) }\n      end\n\n      unless wrapper\n        raise ReeMapper::UnsupportedTypeError, \"wrapper :\#{name} should implement `\\\#{@mapper.strategy_methods.join(', ')}`\"\n      end\n\n      type = ReeMapper::Mapper.build(@mapper.strategies, wrapper.new(subject))\n      type.name = :\#{name}\n\n      field = ReeMapper::Field.new(\n        type,\n        field_name,\n        optional: optional,\n        **opts,\n        location: caller_locations&.first&.to_s,\n      )\n\n      return field unless field_name\n\n      @mapper.add_field(field)\n    end\n\n    def \#{name}?(*args, **opts, &blk)\n      \#{name}(*args, optional: true, **opts, &blk)\n    end\n  RUBY\n\n  self\nend\n", __FILE__, __LINE__ + 1)

Instance Method Details

#hash(field_name, dto: nil, **opts, &blk) ⇒ Object

Raises:



152
153
154
155
156
157
158
159
160
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 152

def hash(field_name, dto: nil, **opts, &blk)
  raise ReeMapper::Error, "invalid DSL usage" unless @mapper

  type = hash_from_blk(dto: dto, &blk)

  field = ReeMapper::Field.new(type, field_name, **opts, location: caller_locations&.first&.to_s)

  @mapper.add_field(field)
end

#hash?(field_name, **opts, &blk) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb', line 163

def hash?(field_name, **opts, &blk)
  hash(field_name, optional: true, **opts, &blk)
end