entity_schema 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +2 -4
  5. data/entity_schema.gemspec +2 -2
  6. data/lib/entity_schema/contracts/belongs_to.rb +5 -7
  7. data/lib/entity_schema/contracts/collection.rb +2 -4
  8. data/lib/entity_schema/contracts/common.rb +8 -9
  9. data/lib/entity_schema/contracts/contract.rb +79 -35
  10. data/lib/entity_schema/contracts/fk_belongs_to.rb +2 -4
  11. data/lib/entity_schema/contracts/object.rb +10 -10
  12. data/lib/entity_schema/contracts/object_belongs_to.rb +2 -4
  13. data/lib/entity_schema/contracts/property.rb +4 -6
  14. data/lib/entity_schema/dsl.rb +27 -24
  15. data/lib/entity_schema/fields/abstract.rb +12 -18
  16. data/lib/entity_schema/fields/fk_belongs_to.rb +2 -2
  17. data/lib/entity_schema/fields/object.rb +2 -2
  18. data/lib/entity_schema/fields/property.rb +1 -1
  19. data/lib/entity_schema/setup_field.rb +8 -8
  20. data/lib/entity_schema/transformers/abstract.rb +72 -0
  21. data/lib/entity_schema/transformers/belongs_to.rb +20 -0
  22. data/lib/entity_schema/{specifications → transformers}/collection.rb +2 -4
  23. data/lib/entity_schema/transformers/common.rb +22 -0
  24. data/lib/entity_schema/transformers/fk_belongs_to.rb +13 -0
  25. data/lib/entity_schema/transformers/object.rb +37 -0
  26. data/lib/entity_schema/transformers/object_belongs_to.rb +10 -0
  27. data/lib/entity_schema/transformers/property.rb +17 -0
  28. data/lib/entity_schema/version.rb +1 -1
  29. metadata +11 -12
  30. data/lib/entity_schema/specifications/abstract.rb +0 -89
  31. data/lib/entity_schema/specifications/belongs_to.rb +0 -22
  32. data/lib/entity_schema/specifications/common.rb +0 -24
  33. data/lib/entity_schema/specifications/fk_belongs_to.rb +0 -15
  34. data/lib/entity_schema/specifications/object.rb +0 -39
  35. data/lib/entity_schema/specifications/object_belongs_to.rb +0 -12
  36. data/lib/entity_schema/specifications/property.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f50c3e3066bc3902e03a7962e8357b1874807a036b396f51e8ca1557f11ead1f
4
- data.tar.gz: bd598fe95948de6c1e50a96a8522f4a7a4fb07a8812292b6d1a7749c381f37d9
3
+ metadata.gz: 9ee8ab3545011ba2dd7016082e6c00bd3d371a789561657fb40f7747c43ab524
4
+ data.tar.gz: 94e051259093bb827d951e05be4b9175d40f103fd31f61fb2c35f6bcec73c5fa
5
5
  SHA512:
6
- metadata.gz: 6a3acb18381e54bf08cff8007c3f26516e6232e5dbadce8cb22b1e168c0f6447f5ae561c6a8ee211f2e64b60a8b4906ad85b63f41b20678b0026bfeea7ce0527
7
- data.tar.gz: 8fdca854597841e095bdd448e89dbc4cf5897591b11f97c5cc60b6bdeff6c78b96e8bbb932df130b69e3de23a933ea1fc84199507825e80a16a67721bddc3f3d
6
+ metadata.gz: f13cd0e8fdad2b33483131c2477f58218beff9160ad2d71c0a83bd083c966bb6d3de4d1878acc86e35c987d15d9f9b42c43c3035245482fa3515611133c2a096
7
+ data.tar.gz: 9abbe10cad5d6b48ee2836a83823d3c8ee6b45302c17085d86b732f4c1f53e15ea3d2bbf023b8c7f88f9f0bb78ab64c15a7bec8de0546afb434704e9b19ca450
data/.rubocop.yml CHANGED
@@ -26,4 +26,4 @@ Style/Documentation:
26
26
  - 'spec/**/*'
27
27
  - 'test/**/*'
28
28
  - 'lib/entity_schema.rb'
29
- - 'lib/entity_schema/specifications/*'
29
+ - 'lib/entity_schema/transformers/*'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- entity_schema (0.1.5)
4
+ entity_schema (0.1.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -101,12 +101,10 @@ _TODO: description_
101
101
 
102
102
  ### `timestamps`
103
103
 
104
- _Not implemented_
105
-
106
104
  Just sugar, same as:
107
105
  ```ruby
108
- property :created_at, **opts
109
- property :updated_at, **opts
106
+ property :created_at, private: :setter, **opts
107
+ property :updated_at, private: :setter, **opts
110
108
  ```
111
109
 
112
110
  ### `object`
@@ -12,8 +12,8 @@ Gem::Specification.new do |spec|
12
12
  spec.email = ['ph-s@mail.ru']
13
13
 
14
14
  spec.summary = 'DSL for describe Entities'
15
- spec.description = 'Simple DSL for describe schema of mapping Hash to entity Object, ' \
16
- 'and then vice-versa'
15
+ spec.description = 'Simple DSL for describe schema of mapping Hash to entity Object ' \
16
+ 'and vice-versa'
17
17
  spec.homepage = 'https://github.com/CaptainPhilipp/entity_schema'
18
18
  spec.license = 'MIT'
19
19
 
@@ -4,12 +4,10 @@ require_relative 'fk_belongs_to'
4
4
  require_relative 'object_belongs_to'
5
5
 
6
6
  module EntitySchema
7
- module Fields
8
- module Contracts
9
- BelongsTo = FkBelongsTo + ObjectBelongsTo + {
10
- fk: { eq: nil, type: Symbol },
11
- pk: { eq: nil, type: Symbol }
12
- }
13
- end
7
+ module Contracts
8
+ BelongsTo = FkBelongsTo + ObjectBelongsTo + [
9
+ fk: { eq: [nil], type: Symbol },
10
+ pk: { eq: [nil], type: Symbol }
11
+ ]
14
12
  end
15
13
  end
@@ -3,9 +3,7 @@
3
3
  require_relative 'object'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- Collection = Object
9
- end
6
+ module Contracts
7
+ Collection = Object
10
8
  end
11
9
  end
@@ -3,14 +3,13 @@
3
3
  require_relative 'contract'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- Common = Contract.new(
9
- key: { eq: nil, type: Symbol },
10
- getter: { eq: [:private, nil] },
11
- setter: { eq: [:private, nil] },
12
- private: { eq: [true, false, :getter, :setter, nil] }
13
- )
14
- end
6
+ module Contracts
7
+ Common = Contract.build(
8
+ { type: Symbol },
9
+ key: { eq: [nil], type: Symbol },
10
+ getter: { eq: [:private, nil] },
11
+ setter: { eq: [:private, nil] },
12
+ private: { eq: [true, false, :getter, :setter, nil] }
13
+ )
15
14
  end
16
15
  end
@@ -1,54 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EntitySchema
4
- module Fields
5
- module Contracts
6
- # Check data with strict contract, described with Hash-based DSL
7
- class Contract
8
- def initialize(rules)
9
- @rules = rules
4
+ module Contracts
5
+ # Check data with strict contract, described with Hash-based DSL
6
+ class Contract
7
+ class << self
8
+ def build(*arguments_arr)
9
+ params = arguments_arr.to_a
10
+ options = params.last.is_a?(Hash) ? params.pop : {}
11
+ new(to_params_hash(params).merge(options))
10
12
  end
11
13
 
12
- def +(other)
13
- self.class.new(rules.merge(other.to_h))
14
+ def to_params_hash(arr)
15
+ arr.each_with_object({}).with_index do |(value, params), i|
16
+ params["argument #{i + 1}"] = value
17
+ end
14
18
  end
19
+ end
15
20
 
16
- def call(raw_options, skip_unknown: false) # rubocop:disable Metrics/AbcSize
17
- raw_options.each do |key, value|
18
- rules.key?(key) || skip_unknown || raise_unknown!(key, value)
21
+ def initialize(rules)
22
+ @rules = rules.dup
23
+ @rules.each_value { |rule| rule.transform_values! { |v| v.nil? ? [nil] : Array(v) } }
24
+ @rules.each(&:freeze).freeze
25
+ freeze
26
+ end
19
27
 
20
- r = rules[key]
21
- next if Array(r[:eq]).any? { |expectation| expectation == value }
22
- next if Array(r[:type]).any? { |type| value.is_a?(type) }
23
- next if Array(r[:respond_to]).any? { |meth| value.respond_to?(meth) }
24
- raise_unexpected_value(r, key, value)
25
- end
26
- true
27
- end
28
+ def +(other)
29
+ args = other.to_a
30
+ options = args.last.is_a?(Hash) ? args.pop : {}
31
+ other_rules = to_params_hash(args).merge(options)
32
+ merge(rules.merge(other_rules))
33
+ end
34
+
35
+ def merge(other)
36
+ other_rules = other.to_h
37
+ self.class.new(rules.merge(other_rules))
38
+ end
28
39
 
29
- def to_h
30
- rules
40
+ def call(*params, skip_unknown: false, **options) # rubocop:disable Metrics/AbcSize
41
+ keyvalue = to_params_hash(params).merge(options)
42
+ keyvalue.each do |key, value|
43
+ rules.key?(key) || skip_unknown || raise_unknown!(key, value)
44
+
45
+ r = rules[key]
46
+ next if r[:eq]&.any? { |expectation| expectation == value }
47
+ next if r[:type]&.any? { |type| value.is_a?(type) }
48
+ next if r[:respond_to]&.any? { |meth| value.respond_to?(meth) }
49
+ raise_unexpected_value(r, key, value)
31
50
  end
51
+ true
52
+ end
32
53
 
33
- private
54
+ def to_h
55
+ rules
56
+ end
34
57
 
35
- attr_reader :rules
58
+ def to_a
59
+ params, options = to_arguments(rules)
60
+ params << options
61
+ end
36
62
 
37
- def raise_unknown!(key, value)
38
- raise "Unknown option `#{key.inspect} => #{value.inspect}` given." \
39
- " Known options: #{rules.keys}"
40
- end
63
+ private
64
+
65
+ attr_reader :rules
66
+
67
+ def to_params_hash(a)
68
+ self.class.to_params_hash(a)
69
+ end
41
70
 
42
- def raise_unexpected_value(rules, key, value)
43
- msg = "Unexpected option value `#{value.inspect}` of option `#{key.inspect}`. \n" \
44
- ' Expected to:'
45
- msgs = []
46
- msgs << "\n be equal to the one of #{rules[:eq]}" if rules.key?(:eq)
47
- msgs << "\n be one of #{rules[:type]}" if rules.key?(:ty)
48
- msgs << "\n respond to one of the methods #{rules[:respond_to]}"
49
- raise TypeError, (msg + msgs * ' OR')
71
+ def to_arguments(hash)
72
+ arr = []
73
+ hash = hash.dup
74
+ hash.each_key do |k|
75
+ arr << hash.delete(k) if k.is_a?(String) && k.start_with?('argument ')
50
76
  end
77
+ [arr, hash]
78
+ end
79
+
80
+ def raise_unknown!(key, value)
81
+ raise "Unknown option `#{key.inspect} => #{value.inspect}` given." \
82
+ " Known options: #{rules.keys}"
83
+ end
84
+
85
+ # rubocop:disable Metrics/LineLength
86
+ def raise_unexpected_value(rules, key, value) # rubocop:disable Metrics/AbcSize
87
+ msg = "Unexpected #{key.inspect} value `#{value.inspect}`. \n" \
88
+ ' Expected to:'
89
+ msgs = []
90
+ msgs << "\n be equal to the one of: #{rules[:eq]&.map(&:inspect)}" if rules.key?(:eq)
91
+ msgs << "\n be one of: #{rules[:type]}" if rules[:type]
92
+ msgs << "\n respond to one of the methods: #{rules[:respond_to]}" if rules.key?(:respond_to)
93
+ raise TypeError, (msg + msgs * ' OR')
51
94
  end
95
+ # rubocop:enable Metrics/LineLength
52
96
  end
53
97
  end
54
98
  end
@@ -3,9 +3,7 @@
3
3
  require_relative 'common'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- FkBelongsTo = Common
9
- end
6
+ module Contracts
7
+ FkBelongsTo = Common
10
8
  end
11
9
  end
@@ -3,15 +3,15 @@
3
3
  require_relative 'common'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- Object = Common + {
9
- mapper: { type: Symbol, eq: nil, respond_to: :call },
10
- map_to: { type: Class, eq: nil },
11
- map_method: { type: Symbol, eq: nil },
12
- serializer: { type: Symbol, eq: nil, respond_to: :call },
13
- serialize: { type: Symbol, eq: nil }
14
- }
15
- end
6
+ module Contracts
7
+ Object = Common + [
8
+ { type: Symbol },
9
+ { type: Class, eq: [nil] },
10
+ mapper: { type: Symbol, eq: [nil], respond_to: :call },
11
+ map_to: { type: Class, eq: [nil] },
12
+ map_method: { type: Symbol, eq: [nil] },
13
+ serializer: { type: Symbol, eq: [nil], respond_to: :call },
14
+ serialize: { type: Symbol, eq: [nil] }
15
+ ]
16
16
  end
17
17
  end
@@ -3,9 +3,7 @@
3
3
  require_relative 'object'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- ObjectBelongsTo = Object
9
- end
6
+ module Contracts
7
+ ObjectBelongsTo = Object
10
8
  end
11
9
  end
@@ -3,11 +3,9 @@
3
3
  require_relative 'common'
4
4
 
5
5
  module EntitySchema
6
- module Fields
7
- module Contracts
8
- Property = Common + {
9
- predicate: { eq: [true, false, nil] }
10
- }
11
- end
6
+ module Contracts
7
+ Property = Common + [
8
+ predicate: { eq: [true, false, nil] }
9
+ ]
12
10
  end
13
11
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'specifications/property'
4
- require_relative 'specifications/object'
5
- require_relative 'specifications/collection'
6
- require_relative 'specifications/belongs_to'
3
+ require_relative 'transformers/property'
4
+ require_relative 'transformers/object'
5
+ require_relative 'transformers/collection'
6
+ require_relative 'transformers/belongs_to'
7
7
 
8
8
  require_relative 'contracts/property'
9
9
  require_relative 'contracts/object'
@@ -27,36 +27,39 @@ module EntitySchema
27
27
  end
28
28
 
29
29
  def property(name, **opts)
30
- Fields::Contracts::Property.(opts)
31
- specicifation = Fields::Specifications::Property.new(name, to_s, opts)
32
- field = Fields::Property.new(specicifation)
33
- setup_field(field, specicifation)
30
+ Contracts::Property.(name, **opts)
31
+ options = Transformers::Property.(name, to_s, nil, opts)
32
+ setup_field Fields::Property.new(options)
34
33
  end
35
34
 
36
- def object(name, **opts)
37
- Fields::Contracts::Object.(opts)
38
- specicifation = Fields::Specifications::Object.new(name, to_s, opts)
39
- field = Fields::Object.new(specicifation)
40
- setup_field(field, specicifation)
35
+ def object(name, type = nil, **opts)
36
+ Contracts::Object.(name, type, **opts)
37
+ options = Transformers::Object.(name, to_s, type, opts)
38
+ setup_field Fields::Object.new(options)
41
39
  end
42
40
 
43
41
  alias has_one object
44
42
 
45
- def collection(name, **opts)
46
- Fields::Contracts::Collection.(opts)
47
- specicifation = Fields::Specifications::Collection.new(name, to_s, opts)
48
- field = Fields::Collection.new(specicifation)
49
- setup_field(field, specicifation)
43
+ def collection(name, type = nil, **opts)
44
+ Contracts::Collection.(name, type, **opts)
45
+ options = Transformers::Collection.(name, to_s, type, opts)
46
+ setup_field Fields::Collection.new(options)
50
47
  end
51
48
 
52
49
  alias has_many collection
53
50
 
54
- def belongs_to(name, **opts)
55
- Fields::Contracts::BelongsTo.(opts)
56
- specicifation = Fields::Specifications::BelongsTo.new(name, to_s, opts)
57
- fk, object = Fields::Builders::BelongsTo.(specicifation)
58
- setup_field(object, specicifation)
59
- setup_field(fk, specicifation)
51
+ def belongs_to(name, type = nil, **opts)
52
+ Contracts::BelongsTo.(name, type, **opts)
53
+ options = Transformers::BelongsTo.(name, to_s, type, opts)
54
+ fk, object = Fields::Builders::BelongsTo.(options)
55
+ setup_field(object)
56
+ setup_field(fk)
57
+ end
58
+
59
+ private
60
+
61
+ def __merge(opts, other)
62
+ opts.merge(other) { |_, old, new| new.nil? ? old : new }
60
63
  end
61
64
  end
62
65
  end
@@ -5,26 +5,28 @@ module EntitySchema
5
5
  # Specification for fiend behaviour: internal and external
6
6
  # will be used for build Field object and for setup Field object
7
7
  class Abstract
8
- attr_reader :src_key, :name
8
+ Specification = Struct.new(:public_getter, :public_setter, :predicate)
9
9
 
10
- def initialize(specification)
11
- @name ||= specification.name
12
- @owner_name = specification.owner_name
13
- @src_key ||= specification.src_key
14
-
15
- @public_getter = specification.public_getter?
16
- @public_setter = specification.public_setter?
10
+ attr_reader :src_key, :name, :specification
17
11
 
12
+ def initialize(options)
13
+ @name ||= options[:name]
14
+ @owner_name = options[:owner_name]
15
+ @src_key ||= options[:src_key]
18
16
  @ivar_name = :"@#{name}"
17
+
18
+ @specification = Specification.new
19
+ @specification.public_getter = options[:public_getter]
20
+ @specification.public_setter = options[:public_setter]
19
21
  end
20
22
 
21
23
  def public_set(obj, value)
22
- raise_public('Setter') unless @public_setter
24
+ raise_public('Setter') unless specification.public_setter
23
25
  set(obj, value)
24
26
  end
25
27
 
26
28
  def public_get(obj)
27
- raise_public('Getter') unless @public_getter
29
+ raise_public('Getter') unless specification.public_getter
28
30
  get(obj)
29
31
  end
30
32
 
@@ -46,14 +48,6 @@ module EntitySchema
46
48
  output[src_key] = read(obj) if given?(obj)
47
49
  end
48
50
 
49
- def public_getter?
50
- @public_getter
51
- end
52
-
53
- def public_setter?
54
- @public_setter
55
- end
56
-
57
51
  private
58
52
 
59
53
  attr_reader :ivar_name, :owner_name, :serialize_method
@@ -9,8 +9,8 @@ module EntitySchema
9
9
  attr_accessor :observer_belongs_to
10
10
 
11
11
  def initialize(options)
12
- @name = options.fk
13
- @src_key = options.fk
12
+ @name = options[:fk]
13
+ @src_key = options[:fk]
14
14
  super(options)
15
15
  end
16
16
 
@@ -7,8 +7,8 @@ module EntitySchema
7
7
  # Associated object
8
8
  class Object < Abstract
9
9
  def initialize(specification)
10
- @mapper = specification.mapper
11
- @serializer = specification.serializer
10
+ @mapper = specification[:mapper]
11
+ @serializer = specification[:serializer]
12
12
  super(specification)
13
13
  end
14
14
 
@@ -9,8 +9,8 @@ module EntitySchema
9
9
  # Simple field with any value
10
10
  class Property < Abstract
11
11
  def initialize(options)
12
- @predicate = options.predicate
13
12
  super(options)
13
+ specification.predicate = options[:predicate]
14
14
  end
15
15
 
16
16
  def get(obj)
@@ -3,34 +3,34 @@
3
3
  module EntitySchema
4
4
  # Define or redefine methods for work with Entity fields
5
5
  module SetupField
6
- def setup_field(field, spec)
6
+ def setup_field(field)
7
7
  entity_schema.add_field(field)
8
8
 
9
9
  setup_getter(field)
10
10
  setup_setter(field)
11
- setup_predicate(field) if spec.predicate?
11
+ setup_predicate(field) if field.specification.predicate
12
12
  end
13
13
 
14
14
  def setup_getter(field)
15
15
  m = field.name
16
16
  define_method(m) { field.get(self) }
17
- public(m) if field.public_getter?
18
- private(m) unless field.public_getter?
17
+ public(m) if field.specification.public_getter
18
+ private(m) unless field.specification.public_getter
19
19
  end
20
20
 
21
21
  def setup_setter(field)
22
22
  m = :"#{field.name}="
23
23
  define_method(m) { |value| field.set(self, value) }
24
- public(m) if field.public_setter?
25
- private(m) unless field.public_setter?
24
+ public(m) if field.specification.public_setter
25
+ private(m) unless field.specification.public_setter
26
26
  end
27
27
 
28
28
  def setup_predicate(field)
29
29
  m = :"#{field.name}?"
30
30
  remove_method(m) if method_defined?(m)
31
31
  define_method(m) { field.get(self) }
32
- public(m) if field.public_getter?
33
- private(m) unless field.public_getter?
32
+ public(m) if field.specification.public_getter
33
+ private(m) unless field.specification.public_getter
34
34
  end
35
35
  end
36
36
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ # Transform raw valid options to usefull options
8
+ class Abstract
9
+ include Singleton
10
+
11
+ def self.call(*args)
12
+ instance.call(*args)
13
+ end
14
+
15
+ def call(name, owner_name, type, raw_options)
16
+ transform_options(name: name, owner_name: owner_name, map_to: type, **raw_options)
17
+ end
18
+
19
+ private
20
+
21
+ # Hook for ancestors
22
+ def transform_options(_options)
23
+ new_strict_hash
24
+ end
25
+
26
+ def bool_key?(key)
27
+ [true, false].include? options.fetch(key, nil)
28
+ end
29
+
30
+ def without_predicate(key)
31
+ key.to_s.delete('?').to_sym
32
+ end
33
+
34
+ def new_strict_hash
35
+ Hash.new do |h, k|
36
+ raise "Gem works wrong: missed option `#{k.inspect}` called. Options is: #{h.keys}"
37
+ end
38
+ end
39
+
40
+ def find(*alternatives)
41
+ alternatives.compact.first
42
+ end
43
+
44
+ # eql(hash, a: 1, b: [1, 2, :value])
45
+ def eql(input, pairs)
46
+ pairs.each do |k, values|
47
+ Array(values).each do |v|
48
+ return true if input[k] == v
49
+ end
50
+ end
51
+ nil
52
+ end
53
+
54
+ def callable(subject)
55
+ subject if subject.respond_to?(:call)
56
+ end
57
+
58
+ def owner_meth(option)
59
+ return unless option.is_a?(Symbol)
60
+ owner.method(option)
61
+ end
62
+
63
+ def truth(subject)
64
+ subject == true ? true : nil
65
+ end
66
+
67
+ def to_bool(subject)
68
+ subject ? true : false
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+ require_relative 'fk_belongs_to'
5
+ require_relative 'object_belongs_to'
6
+
7
+ module EntitySchema
8
+ module Transformers
9
+ class BelongsTo < Object
10
+ private
11
+
12
+ def transform_options(opts)
13
+ super.merge!(
14
+ fk: opts[:fk] || :"#{opts[:name]}_id",
15
+ pk: opts[:pk] || :id
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
@@ -4,10 +4,8 @@ require_relative 'common'
4
4
  require_relative 'object'
5
5
 
6
6
  module EntitySchema
7
- module Fields
8
- module Specifications
9
- class Collection < Specifications::Object
10
- end
7
+ module Transformers
8
+ class Collection < Transformers::Object
11
9
  end
12
10
  end
13
11
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'abstract'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ class Common < Abstract
8
+ private
9
+
10
+ def transform_options(input)
11
+ super.merge!(
12
+ name: input[:name],
13
+ src_key: input[:key] || input[:name],
14
+ owner_name: input[:owner_name],
15
+ public_getter: !eql(input, getter: :private, private: [:getter, true]),
16
+ public_setter: !eql(input, setter: :private, private: [:setter, true]),
17
+ predicate: false
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ class FkBelongsTo < Common
8
+ def transform_options(_name, _owner, _options)
9
+ super.merge!(predicate: false)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ class Object < Common
8
+ private
9
+
10
+ def transform_options(o)
11
+ super.merge!(
12
+ mapper: find(callable(o[:mapper]),
13
+ owner_meth(o[:mapper]),
14
+ mapper(o[:map_to], o[:map_method]),
15
+ default_mapper),
16
+ serializer: find(o[:serializer],
17
+ serializer(o))
18
+ )
19
+ end
20
+
21
+ def mapper(map_to, map_method)
22
+ return if map_to.nil?
23
+ map_method ||= :new
24
+ ->(hash) { map_to.public_send(map_method, hash) }
25
+ end
26
+
27
+ def default_mapper
28
+ ->(hash) { hash }
29
+ end
30
+
31
+ def serializer(opts)
32
+ map_method = opts[:serialize] || :to_h
33
+ ->(object) { object.public_send(map_method) }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ class ObjectBelongsTo < Transformers::Object
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'common'
4
+
5
+ module EntitySchema
6
+ module Transformers
7
+ class Property < Common
8
+ private
9
+
10
+ def transform_options(o)
11
+ super.merge!(
12
+ predicate: to_bool(o[:predicate])
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EntitySchema
4
- VERSION = '0.1.5'
4
+ VERSION = '0.1.6'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entity_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Captain Philipp
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-23 00:00:00.000000000 Z
11
+ date: 2018-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,8 +178,7 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description: Simple DSL for describe schema of mapping Hash to entity Object, and
182
- then vice-versa
181
+ description: Simple DSL for describe schema of mapping Hash to entity Object and vice-versa
183
182
  email:
184
183
  - ph-s@mail.ru
185
184
  executables: []
@@ -226,14 +225,14 @@ files:
226
225
  - lib/entity_schema/instance_methods.rb
227
226
  - lib/entity_schema/schema.rb
228
227
  - lib/entity_schema/setup_field.rb
229
- - lib/entity_schema/specifications/abstract.rb
230
- - lib/entity_schema/specifications/belongs_to.rb
231
- - lib/entity_schema/specifications/collection.rb
232
- - lib/entity_schema/specifications/common.rb
233
- - lib/entity_schema/specifications/fk_belongs_to.rb
234
- - lib/entity_schema/specifications/object.rb
235
- - lib/entity_schema/specifications/object_belongs_to.rb
236
- - lib/entity_schema/specifications/property.rb
228
+ - lib/entity_schema/transformers/abstract.rb
229
+ - lib/entity_schema/transformers/belongs_to.rb
230
+ - lib/entity_schema/transformers/collection.rb
231
+ - lib/entity_schema/transformers/common.rb
232
+ - lib/entity_schema/transformers/fk_belongs_to.rb
233
+ - lib/entity_schema/transformers/object.rb
234
+ - lib/entity_schema/transformers/object_belongs_to.rb
235
+ - lib/entity_schema/transformers/property.rb
237
236
  - lib/entity_schema/version.rb
238
237
  homepage: https://github.com/CaptainPhilipp/entity_schema
239
238
  licenses:
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module EntitySchema
4
- module Fields
5
- module Specifications
6
- # Transform raw valid options to usefull options
7
- class Abstract
8
- def initialize(name, owner_name, raw_options)
9
- @options = transform_options(name: name,
10
- owner_name: owner_name,
11
- **raw_options)
12
- end
13
-
14
- def [](key)
15
- options.fetch(key, nil)
16
- end
17
-
18
- def to_h
19
- options.dup
20
- end
21
-
22
- def method_missing(key, *_args, **_opts)
23
- return options[key] if options.key?(key)
24
- root = without_predicate(key)
25
- return options[root] if bool_key?(root)
26
- super
27
- end
28
-
29
- def respond_to_missing?(key)
30
- options.key?(key) || bool_key?(without_predicate(key))
31
- end
32
-
33
- private
34
-
35
- attr_reader :options
36
-
37
- # Hook for ancestors
38
- def transform_options(_options)
39
- new_strict_hash
40
- end
41
-
42
- def bool_key?(key)
43
- [true, false].include? options.fetch(key, nil)
44
- end
45
-
46
- def without_predicate(key)
47
- key.to_s.delete('?').to_sym
48
- end
49
-
50
- def new_strict_hash
51
- Hash.new do |h, k|
52
- raise "Gem works wrong: missed option `#{k.inspect}` called. Options is: #{h.keys}"
53
- end
54
- end
55
-
56
- def find(*alternatives)
57
- alternatives.compact.first
58
- end
59
-
60
- # eql(hash, a: 1, b: [1, 2, :value])
61
- def eql(input, pairs)
62
- pairs.each do |k, values|
63
- Array(values).each do |v|
64
- return true if input[k] == v
65
- end
66
- end
67
- nil
68
- end
69
-
70
- def callable(subject)
71
- subject if subject.respond_to?(:call)
72
- end
73
-
74
- def owner_meth(option)
75
- return unless option.is_a?(Symbol)
76
- owner.method(option)
77
- end
78
-
79
- def truth(subject)
80
- subject == true ? true : nil
81
- end
82
-
83
- def to_bool(subject)
84
- subject ? true : false
85
- end
86
- end
87
- end
88
- end
89
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'common'
4
- require_relative 'fk_belongs_to'
5
- require_relative 'object_belongs_to'
6
-
7
- module EntitySchema
8
- module Fields
9
- module Specifications
10
- class BelongsTo < Object
11
- private
12
-
13
- def transform_options(opts)
14
- super.merge!(
15
- fk: opts[:fk] || :"#{opts[:name]}_id",
16
- pk: opts[:pk] || :id
17
- )
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'abstract'
4
-
5
- module EntitySchema
6
- module Fields
7
- module Specifications
8
- class Common < Abstract
9
- private
10
-
11
- def transform_options(input)
12
- super.merge!(
13
- name: input[:name],
14
- src_key: input[:key] || input[:name],
15
- owner_name: input[:owner_name],
16
- public_getter: !eql(input, getter: :private, private: [:getter, true]),
17
- public_setter: !eql(input, setter: :private, private: [:setter, true]),
18
- predicate: false
19
- )
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'common'
4
-
5
- module EntitySchema
6
- module Fields
7
- module Specifications
8
- class FkBelongsTo < Common
9
- def transform_options(_name, _owner, _options)
10
- super.merge!(predicate: false)
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'common'
4
-
5
- module EntitySchema
6
- module Fields
7
- module Specifications
8
- class Object < Common
9
- private
10
-
11
- def transform_options(o)
12
- super.merge!(
13
- mapper: find(callable(o[:mapper]),
14
- owner_meth(o[:mapper]),
15
- mapper(o[:map_to], o[:map_method]),
16
- default_mapper),
17
- serializer: find(o[:serializer],
18
- serializer(o))
19
- )
20
- end
21
-
22
- def mapper(map_to, map_method)
23
- return if map_to.nil?
24
- map_method ||= :new
25
- ->(hash) { map_to.public_send(map_method, hash) }
26
- end
27
-
28
- def default_mapper
29
- ->(hash) { hash }
30
- end
31
-
32
- def serializer(opts)
33
- map_method = opts[:serialize] || :to_h
34
- ->(object) { object.public_send(map_method) }
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'common'
4
-
5
- module EntitySchema
6
- module Fields
7
- module Specifications
8
- class ObjectBelongsTo < Specifications::Object
9
- end
10
- end
11
- end
12
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'common'
4
-
5
- module EntitySchema
6
- module Fields
7
- module Specifications
8
- class Property < Common
9
- private
10
-
11
- def transform_options(o)
12
- super.merge!(
13
- predicate: to_bool(o[:predicate])
14
- )
15
- end
16
- end
17
- end
18
- end
19
- end