ree_lib 1.0.93 → 1.0.94
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +3 -1
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +34 -26
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +35 -25
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/base_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/integer_value_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/string_value_enum_mapper.rb +6 -18
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error_with_location.rb +47 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/fields_filter.rb +11 -20
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +36 -48
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/abstract_type.rb +2 -2
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/any.rb +8 -8
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/bool.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date.rb +14 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/date_time.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/float.rb +14 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/integer.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/rational.rb +14 -14
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/string.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/types/time.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/wrappers/array.rb +88 -80
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/benchmarks/mapper_benchmark_spec.rb +41 -1
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +17 -6
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/hash_spec.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/type_options_spec.rb +7 -26
- data/lib/ree_lib/packages/ree_swagger/Package.schema.json +3 -0
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_parameters.rb +2 -1
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_request_body_schema.rb +12 -5
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger/functions/build_serializer_schema.rb +12 -5
- data/lib/ree_lib/packages/ree_swagger/package/ree_swagger.rb +1 -0
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_parameters.schema.json +8 -0
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_request_body_schema.schema.json +1 -1
- data/lib/ree_lib/packages/ree_swagger/schemas/ree_swagger/functions/build_serializer_schema.schema.json +1 -1
- data/lib/ree_lib/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 999bb2c56def52960bba5ba42d451d51720732b56c6133c6b2f31138fd5d1b1b
|
4
|
+
data.tar.gz: fcc8978282f0823ad26d8481c6beba74f3ff622306deabb88a93a466c6b9a476
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd5215c19233b1cedd2e817f7dfde0d2d034148fc548e9116f8f67b98f6678a4d7435b14119a4282840e1f20d9e87d59708e0490282b59074b2cfe38ab979c4a
|
7
|
+
data.tar.gz: d3df53d29afbcb3306437ea20e2d4fc6f36d203853737fd1d7359bc31276d744f5ad092dd4283f5ca94cf0cd36e16af1999bddacbbf2f8bd7f5776d9fe103c38
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ree_lib (1.0.
|
4
|
+
ree_lib (1.0.94)
|
5
5
|
bigdecimal (~> 3.1.6)
|
6
6
|
binding_of_caller (~> 1.0.0)
|
7
7
|
i18n (~> 1.14.1)
|
@@ -73,6 +73,7 @@ GEM
|
|
73
73
|
diff-lcs (>= 1.2.0, < 2.0)
|
74
74
|
rspec-support (~> 3.12.0)
|
75
75
|
rspec-support (3.12.1)
|
76
|
+
ruby-prof (1.7.0)
|
76
77
|
sequel (5.76.0)
|
77
78
|
bigdecimal
|
78
79
|
sqlite3 (1.4.4)
|
@@ -102,6 +103,7 @@ DEPENDENCIES
|
|
102
103
|
roda (~> 3.76.0)
|
103
104
|
rollbar (~> 3.5.1)
|
104
105
|
rspec
|
106
|
+
ruby-prof
|
105
107
|
sqlite3 (~> 1.4.4)
|
106
108
|
timecop (~> 0.9.5)
|
107
109
|
warden (~> 1.2.9)
|
@@ -6,25 +6,29 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
6
6
|
contract(
|
7
7
|
Any,
|
8
8
|
Kwargs[
|
9
|
-
name: String,
|
10
9
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
11
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
12
|
-
location: Nilor[String],
|
10
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
13
11
|
] => Or[Sequel::Postgres::PGArray, String]
|
14
12
|
)
|
15
|
-
def db_dump(value,
|
13
|
+
def db_dump(value, role: nil, fields_filters: nil)
|
16
14
|
if !value.is_a?(Array)
|
17
|
-
raise ReeMapper::TypeError.new("
|
15
|
+
raise ReeMapper::TypeError.new("should be an array, got `#{truncate(value.inspect)}`")
|
18
16
|
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
if subject.fields_filter
|
19
|
+
fields_filters = if fields_filters
|
20
|
+
fields_filters + [subject.fields_filter]
|
21
|
+
else
|
22
|
+
[subject.fields_filter]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
value = value.map.with_index do |item, idx|
|
27
|
+
subject.type.db_dump(item, role:, fields_filters:)
|
28
|
+
rescue ReeMapper::ErrorWithLocation => e
|
29
|
+
e.location ||= subject.location
|
30
|
+
e.prepend_field_name(idx.to_s)
|
31
|
+
raise e
|
28
32
|
end
|
29
33
|
|
30
34
|
if value.empty?
|
@@ -37,25 +41,29 @@ class ReeDao::PgArray < ReeMapper::AbstractWrapper
|
|
37
41
|
contract(
|
38
42
|
Any,
|
39
43
|
Kwargs[
|
40
|
-
name: String,
|
41
44
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
42
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
43
|
-
location: Nilor[String],
|
45
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
44
46
|
] => Array
|
45
47
|
).throws(ReeMapper::TypeError)
|
46
|
-
def db_load(value,
|
48
|
+
def db_load(value, role: nil, fields_filters: nil)
|
47
49
|
if !value.is_a?(Sequel::Postgres::PGArray)
|
48
|
-
raise ReeMapper::TypeError.new("
|
50
|
+
raise ReeMapper::TypeError.new("should be a Sequel::Postgres::PGArray, got `#{truncate(value.inspect)}`")
|
51
|
+
end
|
52
|
+
|
53
|
+
if subject.fields_filter
|
54
|
+
fields_filters = if fields_filters
|
55
|
+
fields_filters + [subject.fields_filter]
|
56
|
+
else
|
57
|
+
[subject.fields_filter]
|
58
|
+
end
|
49
59
|
end
|
50
60
|
|
51
|
-
value.map.with_index do |
|
52
|
-
subject.type.db_load(
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
location: subject.location,
|
58
|
-
)
|
61
|
+
value.map.with_index do |item, idx|
|
62
|
+
subject.type.db_load(item, role:, fields_filters:)
|
63
|
+
rescue ReeMapper::ErrorWithLocation => e
|
64
|
+
e.location ||= subject.location
|
65
|
+
e.prepend_field_name(idx.to_s)
|
66
|
+
raise e
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -6,10 +6,8 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
6
6
|
contract(
|
7
7
|
Any,
|
8
8
|
Kwargs[
|
9
|
-
name: String,
|
10
9
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
11
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
12
|
-
location: Nilor[String],
|
10
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
13
11
|
] => Or[
|
14
12
|
Sequel::Postgres::JSONBHash,
|
15
13
|
Sequel::Postgres::JSONBArray,
|
@@ -21,29 +19,34 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
21
19
|
Sequel::Postgres::JSONBNull
|
22
20
|
]
|
23
21
|
).throws(ReeMapper::TypeError)
|
24
|
-
def db_dump(value,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
22
|
+
def db_dump(value, role: nil, fields_filters: nil)
|
23
|
+
if subject.fields_filter
|
24
|
+
fields_filters = if fields_filters
|
25
|
+
fields_filters + [subject.fields_filter]
|
26
|
+
else
|
27
|
+
[subject.fields_filter]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
value = begin
|
32
|
+
subject.type.db_dump(value, role:, fields_filters:)
|
33
|
+
rescue ReeMapper::ErrorWithLocation => e
|
34
|
+
e.location ||= subject.location
|
35
|
+
raise e
|
36
|
+
end
|
32
37
|
|
33
38
|
begin
|
34
39
|
Sequel.pg_jsonb_wrap(value)
|
35
40
|
rescue Sequel::Error
|
36
|
-
raise ReeMapper::TypeError.new("
|
41
|
+
raise ReeMapper::TypeError.new("should be an jsonb primitive, got `#{truncate(value.inspect)}`")
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
40
45
|
contract(
|
41
46
|
Any,
|
42
47
|
Kwargs[
|
43
|
-
name: String,
|
44
48
|
role: Nilor[Symbol, ArrayOf[Symbol]],
|
45
|
-
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
46
|
-
location: Nilor[String],
|
49
|
+
fields_filters: Nilor[ArrayOf[ReeMapper::FieldsFilter]],
|
47
50
|
] => Or[
|
48
51
|
Hash,
|
49
52
|
Array,
|
@@ -55,7 +58,7 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
55
58
|
Rational,
|
56
59
|
]
|
57
60
|
).throws(ReeMapper::TypeError)
|
58
|
-
def db_load(value,
|
61
|
+
def db_load(value, role: nil, fields_filters: nil)
|
59
62
|
value = case value
|
60
63
|
when Sequel::Postgres::JSONBHash
|
61
64
|
ReeObject::ToHash.new.call(value.to_h)
|
@@ -64,15 +67,22 @@ class ReeDao::PgJsonb < ReeMapper::AbstractWrapper
|
|
64
67
|
when Numeric, String, TrueClass, FalseClass, NilClass
|
65
68
|
value
|
66
69
|
else
|
67
|
-
raise ReeMapper::TypeError.new("
|
70
|
+
raise ReeMapper::TypeError.new("should be a Sequel::Postgres::JSONB, got `#{truncate(value.inspect)}`")
|
68
71
|
end
|
69
72
|
|
70
|
-
subject.
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
if subject.fields_filter
|
74
|
+
fields_filters = if fields_filters
|
75
|
+
fields_filters + [subject.fields_filter]
|
76
|
+
else
|
77
|
+
[subject.fields_filter]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
begin
|
82
|
+
subject.type.db_load(value, role:, fields_filters:)
|
83
|
+
rescue ReeMapper::ErrorWithLocation => e
|
84
|
+
e.location ||= subject.location
|
85
|
+
raise e
|
86
|
+
end
|
77
87
|
end
|
78
|
-
end
|
88
|
+
end
|
@@ -8,29 +8,17 @@ class ReeEnum::BaseEnumMapper < ReeMapper::AbstractType
|
|
8
8
|
@enum = enum
|
9
9
|
end
|
10
10
|
|
11
|
-
contract(
|
12
|
-
|
13
|
-
Kwargs[
|
14
|
-
name: String,
|
15
|
-
location: Nilor[String],
|
16
|
-
] => Or[Integer, String]
|
17
|
-
)
|
18
|
-
def db_dump(value, name:, location: nil)
|
11
|
+
contract(ReeEnum::Value => Or[Integer, String])
|
12
|
+
def db_dump(value)
|
19
13
|
value.mapped_value
|
20
14
|
end
|
21
15
|
|
22
|
-
contract(
|
23
|
-
|
24
|
-
Kwargs[
|
25
|
-
name: String,
|
26
|
-
location: Nilor[String],
|
27
|
-
] => ReeEnum::Value
|
28
|
-
).throws(ReeMapper::CoercionError)
|
29
|
-
def db_load(value, name:, location: nil)
|
16
|
+
contract(Or[Integer, String] => ReeEnum::Value).throws(ReeMapper::CoercionError)
|
17
|
+
def db_load(value)
|
30
18
|
enum_val = @enum.get_values.by_mapped_value(value)
|
31
19
|
|
32
20
|
if !enum_val
|
33
|
-
raise ReeMapper::CoercionError.new("
|
21
|
+
raise ReeMapper::CoercionError.new("should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`")
|
34
22
|
end
|
35
23
|
|
36
24
|
enum_val
|
@@ -41,4 +29,4 @@ class ReeEnum::BaseEnumMapper < ReeMapper::AbstractType
|
|
41
29
|
def enum_inspection
|
42
30
|
@enum_inspection ||= truncate(@enum.get_values.each.map(&:to_s).inspect)
|
43
31
|
end
|
44
|
-
end
|
32
|
+
end
|
@@ -2,25 +2,13 @@
|
|
2
2
|
require_relative "base_enum_mapper"
|
3
3
|
|
4
4
|
class ReeEnum::IntegerValueEnumMapper < ReeEnum::BaseEnumMapper
|
5
|
-
contract(
|
6
|
-
|
7
|
-
Kwargs[
|
8
|
-
name: String,
|
9
|
-
location: Nilor[String],
|
10
|
-
] => Integer
|
11
|
-
)
|
12
|
-
def serialize(value, name:, location: nil)
|
5
|
+
contract(ReeEnum::Value => Integer)
|
6
|
+
def serialize(value)
|
13
7
|
value.value
|
14
8
|
end
|
15
9
|
|
16
|
-
contract(
|
17
|
-
|
18
|
-
Kwargs[
|
19
|
-
name: String,
|
20
|
-
location: Nilor[String],
|
21
|
-
] => ReeEnum::Value
|
22
|
-
).throws(ReeMapper::CoercionError)
|
23
|
-
def cast(value, name:, location: nil)
|
10
|
+
contract(Any => ReeEnum::Value).throws(ReeMapper::CoercionError)
|
11
|
+
def cast(value)
|
24
12
|
enum_value = case value
|
25
13
|
when Integer
|
26
14
|
@enum.get_values.by_value(value)
|
@@ -34,9 +22,9 @@ class ReeEnum::IntegerValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
34
22
|
end
|
35
23
|
|
36
24
|
if enum_value.nil?
|
37
|
-
raise ReeMapper::CoercionError.new("
|
25
|
+
raise ReeMapper::CoercionError.new("should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`")
|
38
26
|
end
|
39
27
|
|
40
28
|
enum_value
|
41
29
|
end
|
42
|
-
end
|
30
|
+
end
|
@@ -2,25 +2,13 @@
|
|
2
2
|
require_relative "base_enum_mapper"
|
3
3
|
|
4
4
|
class ReeEnum::StringValueEnumMapper < ReeEnum::BaseEnumMapper
|
5
|
-
contract(
|
6
|
-
|
7
|
-
Kwargs[
|
8
|
-
name: String,
|
9
|
-
location: Nilor[String],
|
10
|
-
] => String
|
11
|
-
)
|
12
|
-
def serialize(value, name:, location: nil)
|
5
|
+
contract(ReeEnum::Value => String)
|
6
|
+
def serialize(value)
|
13
7
|
value.value
|
14
8
|
end
|
15
9
|
|
16
|
-
contract(
|
17
|
-
|
18
|
-
Kwargs[
|
19
|
-
name: String,
|
20
|
-
location: Nilor[String],
|
21
|
-
] => ReeEnum::Value
|
22
|
-
).throws(ReeMapper::CoercionError)
|
23
|
-
def cast(value, name:, location: nil)
|
10
|
+
contract(Any => ReeEnum::Value).throws(ReeMapper::CoercionError)
|
11
|
+
def cast(value)
|
24
12
|
enum_value = case value
|
25
13
|
when String
|
26
14
|
@enum.get_values.by_value(value)
|
@@ -29,9 +17,9 @@ class ReeEnum::StringValueEnumMapper < ReeEnum::BaseEnumMapper
|
|
29
17
|
end
|
30
18
|
|
31
19
|
if enum_value.nil?
|
32
|
-
raise ReeMapper::CoercionError.new("
|
20
|
+
raise ReeMapper::CoercionError.new("should be one of #{enum_inspection}, got `#{truncate(value.inspect)}`")
|
33
21
|
end
|
34
22
|
|
35
23
|
enum_value
|
36
24
|
end
|
37
|
-
end
|
25
|
+
end
|
@@ -1,25 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ReeMapper::ErrorWithLocation < ReeMapper::Error
|
4
|
-
|
4
|
+
attr_accessor :location
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
super(message)
|
6
|
+
contract(String, String, ArrayOf[String] => Any)
|
7
|
+
def initialize(message, location = nil, field_name_parts = [])
|
8
|
+
@message = message
|
12
9
|
@location = location
|
10
|
+
@field_name_parts = field_name_parts
|
13
11
|
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
contract(String => nil)
|
14
|
+
def prepend_field_name(part)
|
15
|
+
@field_name_parts.unshift part
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
contract(None => Nilor[String])
|
20
|
+
def field_name
|
21
|
+
@field_name_parts.reduce { "#{_1}[#{_2}]" }
|
22
|
+
end
|
23
|
+
|
24
|
+
if ENV["RUBY_ENV"] == "test"
|
25
|
+
|
26
|
+
contract(None => String)
|
27
|
+
def message
|
28
|
+
msg = @message
|
29
|
+
|
30
|
+
if location
|
31
|
+
msg = "#{msg}, located at #{location}"
|
32
|
+
end
|
33
|
+
|
34
|
+
return msg if @field_name_parts.empty?
|
18
35
|
|
19
|
-
|
20
|
-
|
21
|
-
|
36
|
+
"`#{field_name}` #{msg}"
|
37
|
+
end
|
38
|
+
|
39
|
+
else
|
40
|
+
|
41
|
+
def message
|
42
|
+
return @message if @field_name_parts.empty?
|
43
|
+
|
44
|
+
"`#{field_name}` #{@message}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def full_message(...)
|
48
|
+
msg = super
|
49
|
+
return msg if location.nil?
|
50
|
+
|
51
|
+
last_sym_idx = msg.index(/\).*\n/)
|
52
|
+
return msg if last_sym_idx.nil?
|
53
|
+
|
54
|
+
msg.insert(last_sym_idx + 1, ", located at #{location}")
|
55
|
+
end
|
22
56
|
|
23
|
-
msg.insert(idx + 1, ", located at #{location}")
|
24
57
|
end
|
25
58
|
end
|
@@ -33,7 +33,7 @@ class ReeMapper::Field
|
|
33
33
|
@roles = Array(role)
|
34
34
|
@default = default
|
35
35
|
|
36
|
-
@fields_filter = ReeMapper::FieldsFilter.build(only
|
36
|
+
@fields_filter = ReeMapper::FieldsFilter.build(only, except)
|
37
37
|
|
38
38
|
@name_as_str = @name.to_s
|
39
39
|
@name_as_instance_var_name = :"@#{@name}"
|
@@ -55,35 +55,26 @@ class ReeMapper::FieldsFilter
|
|
55
55
|
attr_reader :fields
|
56
56
|
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def self.empty_filter
|
65
|
-
@empty_filter ||= new(NoneStrategy, {}).freeze
|
66
|
-
end
|
67
|
-
|
68
|
-
contract Nilor[ReeMapper::FilterFieldsContract], Nilor[ReeMapper::FilterFieldsContract] => Any
|
69
|
-
def self.build(only:, except:)
|
70
|
-
return empty_filter if only.nil? && except.nil?
|
71
|
-
|
58
|
+
contract(
|
59
|
+
Nilor[ReeMapper::FilterFieldsContract],
|
60
|
+
Nilor[ReeMapper::FilterFieldsContract] => Nilor[ReeMapper::FieldsFilter]
|
61
|
+
)
|
62
|
+
def self.build(only, except)
|
72
63
|
strategy = if !only.nil?
|
73
64
|
OnlyStrategy.new(only, except)
|
74
65
|
elsif !except.nil?
|
75
66
|
ExceptStrategy.new(except)
|
76
67
|
else
|
77
|
-
|
68
|
+
return nil
|
78
69
|
end
|
79
70
|
|
80
71
|
nested_fields_filters = {}
|
81
|
-
|
72
|
+
|
82
73
|
only = only&.select { _1.is_a? Hash }&.reduce(&:merge)
|
83
74
|
except = except&.select { _1.is_a? Hash }&.reduce(&:merge)
|
84
75
|
|
85
|
-
only&.each { nested_fields_filters[_1] = build(
|
86
|
-
except&.each { nested_fields_filters[_1] ||= build(
|
76
|
+
only&.each { nested_fields_filters[_1] = build(_2, except&.dig(_1)) }
|
77
|
+
except&.each { nested_fields_filters[_1] ||= build(nil, _2) }
|
87
78
|
|
88
79
|
new(strategy, nested_fields_filters)
|
89
80
|
end
|
@@ -98,9 +89,9 @@ class ReeMapper::FieldsFilter
|
|
98
89
|
end
|
99
90
|
|
100
91
|
def filter_for(field)
|
101
|
-
nested_fields_filters
|
92
|
+
nested_fields_filters[field]
|
102
93
|
end
|
103
94
|
|
104
95
|
private
|
105
96
|
attr_reader :strategy, :nested_fields_filters
|
106
|
-
end
|
97
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ReeMapper::Mapper
|
4
|
-
EMPTY_ARY = [].freeze
|
5
|
-
|
6
4
|
contract(
|
7
5
|
ArrayOf[ReeMapper::MapperStrategy],
|
8
6
|
Nilor[ReeMapper::AbstractType, ReeMapper::AbstractWrapper] => self
|
@@ -25,77 +23,67 @@ class ReeMapper::Mapper
|
|
25
23
|
|
26
24
|
if type
|
27
25
|
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
28
|
-
def #{method}(obj,
|
26
|
+
def #{method}(obj, role: nil, only: nil, except: nil, fields_filters: nil)
|
29
27
|
#{
|
30
28
|
if type.is_a?(ReeMapper::AbstractWrapper)
|
31
|
-
"@type.#{method}(obj,
|
29
|
+
"@type.#{method}(obj, role:, fields_filters:)"
|
32
30
|
else
|
33
|
-
"@type.#{method}(obj
|
31
|
+
"@type.#{method}(obj)"
|
34
32
|
end
|
35
33
|
}
|
36
34
|
end
|
37
35
|
RUBY
|
38
36
|
else
|
39
37
|
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
40
|
-
def #{method}(obj,
|
41
|
-
|
42
|
-
raise ReeMapper::ArgumentError, "Invalid `only` format"
|
43
|
-
end
|
44
|
-
|
45
|
-
if except && !ReeMapper::FilterFieldsContract.valid?(except)
|
46
|
-
raise ReeMapper::ArgumentError, "Invalid `except` format"
|
47
|
-
end
|
38
|
+
def #{method}(obj, role: nil, only: nil, except: nil, fields_filters: nil)
|
39
|
+
user_fields_filter = ReeMapper::FieldsFilter.build(only, except)
|
48
40
|
|
49
|
-
user_fields_filter
|
50
|
-
|
51
|
-
|
52
|
-
field_fields_filters = if user_fields_filter == ReeMapper::FieldsFilter::NoneStrategy
|
53
|
-
fields_filters
|
41
|
+
if !user_fields_filter.nil?
|
42
|
+
fields_filters = if fields_filters.nil?
|
43
|
+
[user_fields_filter]
|
54
44
|
else
|
55
45
|
fields_filters + [user_fields_filter]
|
56
46
|
end
|
47
|
+
end
|
57
48
|
|
58
|
-
|
49
|
+
@fields.each_with_object(@#{method}_strategy.build_object) do |(_, field), acc|
|
50
|
+
next unless fields_filters.nil? || fields_filters.all? { _1.allow? field.name }
|
59
51
|
next unless field.has_role?(role)
|
60
52
|
|
61
|
-
|
62
|
-
is_optional = field.optional || @#{method}_strategy.always_optional
|
63
|
-
|
64
|
-
if !is_with_value && !is_optional
|
65
|
-
raise ReeMapper::TypeError.new(
|
66
|
-
"Missing required field `\#{field.from_as_str}` for `\#{name || 'root'}`",
|
67
|
-
field.location
|
68
|
-
)
|
69
|
-
end
|
70
|
-
|
71
|
-
next if !is_with_value && !field.has_default?
|
72
|
-
|
73
|
-
value = if is_with_value
|
53
|
+
value = if @#{method}_strategy.has_value?(obj, field)
|
74
54
|
@#{method}_strategy.get_value(obj, field)
|
75
55
|
else
|
56
|
+
if !field.optional && !@#{method}_strategy.always_optional
|
57
|
+
raise ReeMapper::TypeError.new(
|
58
|
+
"is missing required field",
|
59
|
+
field.location,
|
60
|
+
[field.from_as_str]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
next unless field.has_default?
|
65
|
+
|
76
66
|
field.default
|
77
67
|
end
|
78
68
|
|
79
|
-
|
80
|
-
|
69
|
+
if !value.nil? || !field.null
|
70
|
+
nested_fields_filters = fields_filters&.filter_map { _1.filter_for(field.name) }
|
81
71
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
72
|
+
if field.fields_filter
|
73
|
+
nested_fields_filters = if nested_fields_filters
|
74
|
+
nested_fields_filters + [field.fields_filter]
|
75
|
+
else
|
76
|
+
[field.fields_filter]
|
77
|
+
end
|
86
78
|
end
|
87
79
|
|
88
|
-
|
89
|
-
|
80
|
+
value = begin
|
81
|
+
field.type.#{method}(value, role:, fields_filters: nested_fields_filters)
|
82
|
+
rescue ReeMapper::ErrorWithLocation => e
|
83
|
+
e.prepend_field_name field.name_as_str
|
84
|
+
e.location ||= field.location
|
85
|
+
raise e
|
90
86
|
end
|
91
|
-
|
92
|
-
value = field.type.#{method}(
|
93
|
-
value,
|
94
|
-
name: nested_name,
|
95
|
-
role: role,
|
96
|
-
fields_filters: nested_fields_filters,
|
97
|
-
location: field.location,
|
98
|
-
)
|
99
87
|
end
|
100
88
|
|
101
89
|
@#{method}_strategy.assign_value(acc, field, value)
|
@@ -1,23 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class ReeMapper::Any < ReeMapper::AbstractType
|
4
|
-
contract(Any
|
5
|
-
def serialize(value
|
4
|
+
contract(Any => Any)
|
5
|
+
def serialize(value)
|
6
6
|
value
|
7
7
|
end
|
8
8
|
|
9
|
-
contract(Any
|
10
|
-
def cast(value
|
9
|
+
contract(Any => Any)
|
10
|
+
def cast(value)
|
11
11
|
value
|
12
12
|
end
|
13
13
|
|
14
|
-
contract(Any
|
15
|
-
def db_dump(value
|
14
|
+
contract(Any => Any)
|
15
|
+
def db_dump(value)
|
16
16
|
value
|
17
17
|
end
|
18
18
|
|
19
|
-
contract(Any
|
20
|
-
def db_load(value
|
19
|
+
contract(Any => Any)
|
20
|
+
def db_load(value)
|
21
21
|
value
|
22
22
|
end
|
23
23
|
end
|