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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +2 -4
- data/entity_schema.gemspec +2 -2
- data/lib/entity_schema/contracts/belongs_to.rb +5 -7
- data/lib/entity_schema/contracts/collection.rb +2 -4
- data/lib/entity_schema/contracts/common.rb +8 -9
- data/lib/entity_schema/contracts/contract.rb +79 -35
- data/lib/entity_schema/contracts/fk_belongs_to.rb +2 -4
- data/lib/entity_schema/contracts/object.rb +10 -10
- data/lib/entity_schema/contracts/object_belongs_to.rb +2 -4
- data/lib/entity_schema/contracts/property.rb +4 -6
- data/lib/entity_schema/dsl.rb +27 -24
- data/lib/entity_schema/fields/abstract.rb +12 -18
- data/lib/entity_schema/fields/fk_belongs_to.rb +2 -2
- data/lib/entity_schema/fields/object.rb +2 -2
- data/lib/entity_schema/fields/property.rb +1 -1
- data/lib/entity_schema/setup_field.rb +8 -8
- data/lib/entity_schema/transformers/abstract.rb +72 -0
- data/lib/entity_schema/transformers/belongs_to.rb +20 -0
- data/lib/entity_schema/{specifications → transformers}/collection.rb +2 -4
- data/lib/entity_schema/transformers/common.rb +22 -0
- data/lib/entity_schema/transformers/fk_belongs_to.rb +13 -0
- data/lib/entity_schema/transformers/object.rb +37 -0
- data/lib/entity_schema/transformers/object_belongs_to.rb +10 -0
- data/lib/entity_schema/transformers/property.rb +17 -0
- data/lib/entity_schema/version.rb +1 -1
- metadata +11 -12
- data/lib/entity_schema/specifications/abstract.rb +0 -89
- data/lib/entity_schema/specifications/belongs_to.rb +0 -22
- data/lib/entity_schema/specifications/common.rb +0 -24
- data/lib/entity_schema/specifications/fk_belongs_to.rb +0 -15
- data/lib/entity_schema/specifications/object.rb +0 -39
- data/lib/entity_schema/specifications/object_belongs_to.rb +0 -12
- data/lib/entity_schema/specifications/property.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ee8ab3545011ba2dd7016082e6c00bd3d371a789561657fb40f7747c43ab524
|
4
|
+
data.tar.gz: 94e051259093bb827d951e05be4b9175d40f103fd31f61fb2c35f6bcec73c5fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f13cd0e8fdad2b33483131c2477f58218beff9160ad2d71c0a83bd083c966bb6d3de4d1878acc86e35c987d15d9f9b42c43c3035245482fa3515611133c2a096
|
7
|
+
data.tar.gz: 9abbe10cad5d6b48ee2836a83823d3c8ee6b45302c17085d86b732f4c1f53e15ea3d2bbf023b8c7f88f9f0bb78ab64c15a7bec8de0546afb434704e9b19ca450
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
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`
|
data/entity_schema.gemspec
CHANGED
@@ -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
|
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
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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,14 +3,13 @@
|
|
3
3
|
require_relative 'contract'
|
4
4
|
|
5
5
|
module EntitySchema
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
5
|
-
|
6
|
-
|
7
|
-
class
|
8
|
-
def
|
9
|
-
|
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
|
13
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
54
|
+
def to_h
|
55
|
+
rules
|
56
|
+
end
|
34
57
|
|
35
|
-
|
58
|
+
def to_a
|
59
|
+
params, options = to_arguments(rules)
|
60
|
+
params << options
|
61
|
+
end
|
36
62
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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,15 +3,15 @@
|
|
3
3
|
require_relative 'common'
|
4
4
|
|
5
5
|
module EntitySchema
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
}
|
15
|
-
|
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,11 +3,9 @@
|
|
3
3
|
require_relative 'common'
|
4
4
|
|
5
5
|
module EntitySchema
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
11
|
-
end
|
6
|
+
module Contracts
|
7
|
+
Property = Common + [
|
8
|
+
predicate: { eq: [true, false, nil] }
|
9
|
+
]
|
12
10
|
end
|
13
11
|
end
|
data/lib/entity_schema/dsl.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
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
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
56
|
-
|
57
|
-
fk, object = Fields::Builders::BelongsTo.(
|
58
|
-
setup_field(object
|
59
|
-
setup_field(fk
|
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
|
-
|
8
|
+
Specification = Struct.new(:public_getter, :public_setter, :predicate)
|
9
9
|
|
10
|
-
|
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
|
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
|
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
|
@@ -7,8 +7,8 @@ module EntitySchema
|
|
7
7
|
# Associated object
|
8
8
|
class Object < Abstract
|
9
9
|
def initialize(specification)
|
10
|
-
@mapper = specification
|
11
|
-
@serializer = specification
|
10
|
+
@mapper = specification[:mapper]
|
11
|
+
@serializer = specification[:serializer]
|
12
12
|
super(specification)
|
13
13
|
end
|
14
14
|
|
@@ -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
|
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
|
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
|
@@ -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,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,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
|
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.
|
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-
|
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
|
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/
|
230
|
-
- lib/entity_schema/
|
231
|
-
- lib/entity_schema/
|
232
|
-
- lib/entity_schema/
|
233
|
-
- lib/entity_schema/
|
234
|
-
- lib/entity_schema/
|
235
|
-
- lib/entity_schema/
|
236
|
-
- lib/entity_schema/
|
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,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
|