ree_lib 1.0.86 → 1.0.88
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/.ruby-version +1 -1
- data/Gemfile.lock +28 -23
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_array.rb +12 -8
- data/lib/ree_lib/packages/ree_dao/package/ree_dao/wrappers/pg_jsonb.rb +12 -8
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_array_spec.rb +3 -3
- data/lib/ree_lib/packages/ree_dao/spec/ree_dao/wrappers/pg_jsonb_spec.rb +4 -4
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/base_enum_mapper.rb +5 -5
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/integer_value_enum_mapper.rb +5 -5
- data/lib/ree_lib/packages/ree_enum/package/ree_enum/string_value_enum_mapper.rb +5 -5
- data/lib/ree_lib/packages/ree_enum/spec/ree_enum/dsl_spec.rb +3 -3
- data/lib/ree_lib/packages/ree_http/package/ree_http/functions/execute_request.rb +27 -20
- data/lib/ree_lib/packages/ree_http/schemas/ree_http/functions/execute_request.schema.json +8 -0
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_delete_spec.rb +10 -8
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_get_spec.rb +79 -18
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_options_spec.rb +6 -5
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_patch_spec.rb +8 -4
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_post_spec.rb +5 -10
- data/lib/ree_lib/packages/ree_http/spec/ree_http/functions/http_put_spec.rb +5 -3
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/coercion_error.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/error_with_location.rb +25 -0
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/errors/type_error.rb +1 -1
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/field.rb +12 -4
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper.rb +32 -10
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper/mapper_factory.rb +17 -4
- 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 +13 -13
- 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 +13 -13
- 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 +13 -13
- 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 +73 -21
- data/lib/ree_lib/packages/ree_mapper/package/ree_mapper.rb +1 -0
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/benchmarks/mapper_benchmark_spec.rb +31 -0
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_factory_spec.rb +10 -6
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/mapper_spec.rb +7 -0
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/bool_spec.rb +8 -8
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/date_spec.rb +10 -10
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/date_time_spec.rb +16 -16
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/float_spec.rb +13 -13
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/hash_spec.rb +2 -2
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/integer_spec.rb +14 -14
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/rational_spec.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/string_spec.rb +12 -12
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/time_spec.rb +17 -16
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/types/type_options_spec.rb +4 -4
- data/lib/ree_lib/packages/ree_mapper/spec/ree_mapper/wrappers/array_spec.rb +6 -6
- data/lib/ree_lib/spec.init.rb +3 -1
- data/lib/ree_lib/version.rb +1 -1
- metadata +19 -3
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
require 'date'
|
|
4
4
|
|
|
5
5
|
class ReeMapper::DateTime < ReeMapper::AbstractType
|
|
6
|
-
contract(Any, Kwargs[name: String,
|
|
7
|
-
def serialize(value, name:,
|
|
6
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => DateTime).throws(ReeMapper::TypeError)
|
|
7
|
+
def serialize(value, name:, location: nil)
|
|
8
8
|
if value.class == DateTime
|
|
9
9
|
value
|
|
10
10
|
else
|
|
11
|
-
raise ReeMapper::TypeError
|
|
11
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a datetime, got `#{truncate(value.inspect)}`", location)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
contract(Any, Kwargs[name: String,
|
|
16
|
-
def cast(value, name:,
|
|
15
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => DateTime).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
16
|
+
def cast(value, name:, location: nil)
|
|
17
17
|
if value.class == DateTime
|
|
18
18
|
value
|
|
19
19
|
elsif value.class == Time
|
|
@@ -22,20 +22,20 @@ class ReeMapper::DateTime < ReeMapper::AbstractType
|
|
|
22
22
|
begin
|
|
23
23
|
ReeDatetime::InDefaultTimeZone.new.call(DateTime.parse(value))
|
|
24
24
|
rescue ArgumentError
|
|
25
|
-
raise ReeMapper::CoercionError
|
|
25
|
+
raise ReeMapper::CoercionError.new("`#{name}` is invalid datetime, got `#{truncate(value.inspect)}`", location)
|
|
26
26
|
end
|
|
27
27
|
else
|
|
28
|
-
raise ReeMapper::TypeError
|
|
28
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a datetime, got `#{truncate(value.inspect)}`", location)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
contract(Any, Kwargs[name: String,
|
|
33
|
-
def db_dump(value, name:,
|
|
34
|
-
serialize(value, name: name,
|
|
32
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => DateTime).throws(ReeMapper::TypeError)
|
|
33
|
+
def db_dump(value, name:, location: nil)
|
|
34
|
+
serialize(value, name: name, location: location)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
contract(Any, Kwargs[name: String,
|
|
38
|
-
def db_load(value, name:,
|
|
39
|
-
cast(value, name: name,
|
|
37
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => DateTime).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
38
|
+
def db_load(value, name:, location: nil)
|
|
39
|
+
cast(value, name: name, location: location)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::Float < ReeMapper::AbstractType
|
|
4
|
-
contract(Any, Kwargs[name: String,
|
|
5
|
-
def serialize(value, name:,
|
|
4
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Float).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value, name:, location: nil)
|
|
6
6
|
if value.is_a?(Float)
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError
|
|
9
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a float, got `#{truncate(value.inspect)}`", location)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any, Kwargs[name: String,
|
|
14
|
-
def cast(value, name:,
|
|
13
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Float).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
14
|
+
def cast(value, name:, location: nil)
|
|
15
15
|
if value.is_a?(Numeric)
|
|
16
16
|
value.to_f
|
|
17
17
|
elsif value.is_a?(String)
|
|
18
18
|
begin
|
|
19
19
|
Float(value)
|
|
20
20
|
rescue ArgumentError => e
|
|
21
|
-
raise ReeMapper::CoercionError
|
|
21
|
+
raise ReeMapper::CoercionError.new("`#{name}` is invalid float, got `#{truncate(value.inspect)}`", location)
|
|
22
22
|
end
|
|
23
23
|
elsif defined?(BigDecimal) && value.is_a?(BigDecimal)
|
|
24
24
|
value.to_f
|
|
25
25
|
else
|
|
26
|
-
raise ReeMapper::TypeError
|
|
26
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a float, got `#{truncate(value.inspect)}`", location)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
contract(Any, Kwargs[name: String,
|
|
31
|
-
def db_dump(value, name:,
|
|
32
|
-
serialize(value, name: name,
|
|
30
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Float).throws(ReeMapper::CoercionError)
|
|
31
|
+
def db_dump(value, name:, location: nil)
|
|
32
|
+
serialize(value, name: name, location: location)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
contract(Any, Kwargs[name: String,
|
|
36
|
-
def db_load(value, name:,
|
|
37
|
-
cast(value, name: name,
|
|
35
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Float).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
36
|
+
def db_load(value, name:, location: nil)
|
|
37
|
+
cast(value, name: name, location: location)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::Integer < ReeMapper::AbstractType
|
|
4
|
-
contract(Any, Kwargs[name: String,
|
|
5
|
-
def serialize(value, name:,
|
|
4
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Integer).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value, name:, location: nil)
|
|
6
6
|
if value.is_a? Integer
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError
|
|
9
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an integer, got `#{truncate(value.inspect)}`", location)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any
|
|
14
|
-
def cast(value, name:,
|
|
13
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Integer).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
14
|
+
def cast(value, name:, location: nil)
|
|
15
15
|
if value.is_a?(Integer)
|
|
16
16
|
value
|
|
17
17
|
elsif value.is_a?(String)
|
|
18
18
|
coerced_value = Integer(value, exception: false)
|
|
19
19
|
if coerced_value.nil?
|
|
20
|
-
raise ReeMapper::CoercionError
|
|
20
|
+
raise ReeMapper::CoercionError.new("`#{name}` is invalid integer, got `#{truncate(value.inspect)}`", location)
|
|
21
21
|
end
|
|
22
22
|
coerced_value
|
|
23
23
|
else
|
|
24
|
-
raise ReeMapper::TypeError
|
|
24
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an integer, got `#{truncate(value.inspect)}`", location)
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
contract(Any, Kwargs[name: String,
|
|
29
|
-
def db_dump(value, name:,
|
|
30
|
-
serialize(value, name: name,
|
|
28
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Integer).throws(ReeMapper::TypeError)
|
|
29
|
+
def db_dump(value, name:, location: nil)
|
|
30
|
+
serialize(value, name: name, location: location)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
contract(Any, Kwargs[name: String,
|
|
34
|
-
def db_load(value, name:,
|
|
35
|
-
cast(value, name: name,
|
|
33
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Integer).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
34
|
+
def db_load(value, name:, location: nil)
|
|
35
|
+
cast(value, name: name, location: location)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::Rational < ReeMapper::AbstractType
|
|
4
|
-
contract(Any, Kwargs[name: String,
|
|
5
|
-
def serialize(value, name:,
|
|
4
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Rational).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value, name:, location: nil)
|
|
6
6
|
if value.is_a?(Rational)
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError
|
|
9
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a rational, got `#{truncate(value.inspect)}`", location)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any, Kwargs[name: String,
|
|
14
|
-
def cast(value, name:,
|
|
13
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Rational).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
14
|
+
def cast(value, name:, location: nil)
|
|
15
15
|
if value.is_a?(Rational)
|
|
16
16
|
value
|
|
17
17
|
elsif value.is_a?(String)
|
|
18
18
|
begin
|
|
19
19
|
Rational(value)
|
|
20
20
|
rescue ArgumentError, ZeroDivisionError => e
|
|
21
|
-
raise ReeMapper::CoercionError
|
|
21
|
+
raise ReeMapper::CoercionError.new("`#{name}` is invalid rational, got `#{truncate(value.inspect)}`", location)
|
|
22
22
|
end
|
|
23
23
|
elsif value.is_a?(Numeric)
|
|
24
24
|
Rational(value)
|
|
25
25
|
else
|
|
26
|
-
raise ReeMapper::TypeError
|
|
26
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a rational, got `#{truncate(value.inspect)}`", location)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
contract(Any, Kwargs[name: String,
|
|
31
|
-
def db_dump(value, name:,
|
|
32
|
-
serialize(value, name: name,
|
|
30
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => String)
|
|
31
|
+
def db_dump(value, name:, location: nil)
|
|
32
|
+
serialize(value, name: name, location: location).to_s
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
contract(Any, Kwargs[name: String,
|
|
36
|
-
def db_load(value, name:,
|
|
37
|
-
cast(value, name: name,
|
|
35
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Rational)
|
|
36
|
+
def db_load(value, name:, location: nil)
|
|
37
|
+
cast(value, name: name, location: location)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::String < ReeMapper::AbstractType
|
|
4
|
-
contract(Any, Kwargs[name: String,
|
|
5
|
-
def serialize(value, name:,
|
|
4
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => String).throws(ReeMapper::TypeError)
|
|
5
|
+
def serialize(value, name:, location: nil)
|
|
6
6
|
if value.is_a? String
|
|
7
7
|
value
|
|
8
8
|
else
|
|
9
|
-
raise ReeMapper::TypeError
|
|
9
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a string, got `#{truncate(value.inspect)}`", location)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
contract(Any, Kwargs[name: String,
|
|
14
|
-
def cast(value, name:,
|
|
15
|
-
serialize(value, name: name,
|
|
13
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => String).throws(ReeMapper::TypeError)
|
|
14
|
+
def cast(value, name:, location: nil)
|
|
15
|
+
serialize(value, name: name, location: location)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
contract(Any, Kwargs[name: String,
|
|
19
|
-
def db_dump(value, name:,
|
|
20
|
-
serialize(value, name: name,
|
|
18
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => String).throws(ReeMapper::TypeError)
|
|
19
|
+
def db_dump(value, name:, location: nil)
|
|
20
|
+
serialize(value, name: name, location: location)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
contract(Any, Kwargs[name: String,
|
|
24
|
-
def db_load(value, name:,
|
|
25
|
-
serialize(value, name: name,
|
|
23
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => String).throws(ReeMapper::TypeError)
|
|
24
|
+
def db_load(value, name:, location: nil)
|
|
25
|
+
serialize(value, name: name, location: location)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
require 'time'
|
|
4
4
|
|
|
5
5
|
class ReeMapper::Time < ReeMapper::AbstractType
|
|
6
|
-
contract(Any, Kwargs[name: String,
|
|
7
|
-
def serialize(value, name:,
|
|
6
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Time).throws(ReeMapper::TypeError)
|
|
7
|
+
def serialize(value, name:, location: nil)
|
|
8
8
|
if value.class == Time
|
|
9
9
|
value
|
|
10
10
|
else
|
|
11
|
-
raise ReeMapper::TypeError
|
|
11
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a time, got `#{truncate(value.inspect)}`", location)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
contract(Any, Kwargs[name: String,
|
|
16
|
-
def cast(value, name:,
|
|
15
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Time).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
16
|
+
def cast(value, name:, location: nil)
|
|
17
17
|
if value.class == Time
|
|
18
18
|
value
|
|
19
19
|
elsif value.class == DateTime
|
|
@@ -22,20 +22,20 @@ class ReeMapper::Time < ReeMapper::AbstractType
|
|
|
22
22
|
begin
|
|
23
23
|
Time.parse(value)
|
|
24
24
|
rescue ArgumentError
|
|
25
|
-
raise ReeMapper::CoercionError
|
|
25
|
+
raise ReeMapper::CoercionError.new("`#{name}` is invalid time, got `#{truncate(value.inspect)}`", location)
|
|
26
26
|
end
|
|
27
27
|
else
|
|
28
|
-
raise ReeMapper::TypeError
|
|
28
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a time, got `#{truncate(value.inspect)}`", location)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
contract(Any, Kwargs[name: String,
|
|
33
|
-
def db_dump(value, name:,
|
|
34
|
-
serialize(value, name: name,
|
|
32
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Time).throws(ReeMapper::TypeError)
|
|
33
|
+
def db_dump(value, name:, location: nil)
|
|
34
|
+
serialize(value, name: name, location: location)
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
contract(Any, Kwargs[name: String,
|
|
38
|
-
def db_load(value, name:,
|
|
39
|
-
cast(value, name: name,
|
|
37
|
+
contract(Any, Kwargs[name: String, location: Nilor[String]] => Time).throws(ReeMapper::CoercionError, ReeMapper::TypeError)
|
|
38
|
+
def db_load(value, name:, location: nil)
|
|
39
|
+
cast(value, name: name, location: location)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -1,67 +1,119 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class ReeMapper::Array < ReeMapper::AbstractWrapper
|
|
4
|
-
contract(
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
contract(
|
|
5
|
+
Any,
|
|
6
|
+
Kwargs[
|
|
7
|
+
name: String,
|
|
8
|
+
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
9
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
10
|
+
location: Nilor[String],
|
|
11
|
+
] => Array
|
|
12
|
+
).throws(ReeMapper::TypeError)
|
|
13
|
+
def serialize(value, name:, role: nil, fields_filters: [], location: nil)
|
|
7
14
|
if value.is_a?(Array)
|
|
8
15
|
value.map.with_index {
|
|
9
16
|
if _1.nil? && subject.null
|
|
10
17
|
_1
|
|
11
18
|
else
|
|
12
|
-
subject.type.serialize(
|
|
19
|
+
subject.type.serialize(
|
|
20
|
+
_1,
|
|
21
|
+
name: "#{name}[#{_2}]",
|
|
22
|
+
role: role,
|
|
23
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
|
24
|
+
location: subject.location,
|
|
25
|
+
)
|
|
13
26
|
end
|
|
14
27
|
}
|
|
15
28
|
else
|
|
16
|
-
raise ReeMapper::TypeError
|
|
29
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an array, got `#{truncate(value.inspect)}`", location)
|
|
17
30
|
end
|
|
18
31
|
end
|
|
19
32
|
|
|
20
|
-
contract(
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
contract(
|
|
34
|
+
Any,
|
|
35
|
+
Kwargs[
|
|
36
|
+
name: String,
|
|
37
|
+
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
38
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
39
|
+
location: Nilor[String],
|
|
40
|
+
] => Array
|
|
41
|
+
).throws(ReeMapper::TypeError)
|
|
42
|
+
def cast(value, name:, role: nil, fields_filters: [], location: nil)
|
|
23
43
|
if value.is_a?(Array)
|
|
24
44
|
value.map.with_index {
|
|
25
45
|
if _1.nil? && subject.null
|
|
26
46
|
_1
|
|
27
47
|
else
|
|
28
|
-
subject.type.cast(
|
|
48
|
+
subject.type.cast(
|
|
49
|
+
_1,
|
|
50
|
+
name: "#{name}[#{_2}]",
|
|
51
|
+
role: role,
|
|
52
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
|
53
|
+
location: subject.location,
|
|
54
|
+
)
|
|
29
55
|
end
|
|
30
56
|
}
|
|
31
57
|
else
|
|
32
|
-
raise ReeMapper::TypeError
|
|
58
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an array, got `#{truncate(value.inspect)}`", location)
|
|
33
59
|
end
|
|
34
60
|
end
|
|
35
61
|
|
|
36
|
-
contract(
|
|
37
|
-
|
|
38
|
-
|
|
62
|
+
contract(
|
|
63
|
+
Any,
|
|
64
|
+
Kwargs[
|
|
65
|
+
name: String,
|
|
66
|
+
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
67
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
68
|
+
location: Nilor[String],
|
|
69
|
+
] => Array
|
|
70
|
+
).throws(ReeMapper::TypeError)
|
|
71
|
+
def db_dump(value, name:, role: nil, fields_filters: [], location: nil)
|
|
39
72
|
if value.is_a?(Array)
|
|
40
73
|
value.map.with_index {
|
|
41
74
|
if _1.nil? && subject.null
|
|
42
75
|
_1
|
|
43
76
|
else
|
|
44
|
-
subject.type.db_dump(
|
|
77
|
+
subject.type.db_dump(
|
|
78
|
+
_1,
|
|
79
|
+
name: "#{name}[#{_2}]",
|
|
80
|
+
role: role,
|
|
81
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
|
82
|
+
location: subject.location,
|
|
83
|
+
)
|
|
45
84
|
end
|
|
46
85
|
}
|
|
47
86
|
else
|
|
48
|
-
raise ReeMapper::TypeError
|
|
87
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an array, got `#{truncate(value.inspect)}`", location)
|
|
49
88
|
end
|
|
50
89
|
end
|
|
51
90
|
|
|
52
|
-
contract(
|
|
53
|
-
|
|
54
|
-
|
|
91
|
+
contract(
|
|
92
|
+
Any,
|
|
93
|
+
Kwargs[
|
|
94
|
+
name: String,
|
|
95
|
+
role: Nilor[Symbol, ArrayOf[Symbol]],
|
|
96
|
+
fields_filters: ArrayOf[ReeMapper::FieldsFilter],
|
|
97
|
+
location: Nilor[String],
|
|
98
|
+
] => Array
|
|
99
|
+
).throws(ReeMapper::TypeError)
|
|
100
|
+
def db_load(value, name:, role: nil, fields_filters: [], location: nil)
|
|
55
101
|
if value.is_a?(Array)
|
|
56
102
|
value.map.with_index {
|
|
57
103
|
if _1.nil? && subject.null
|
|
58
104
|
_1
|
|
59
105
|
else
|
|
60
|
-
subject.type.db_load(
|
|
106
|
+
subject.type.db_load(
|
|
107
|
+
_1,
|
|
108
|
+
name: "#{name}[#{_2}]",
|
|
109
|
+
role: role,
|
|
110
|
+
fields_filters: fields_filters + [subject.fields_filter],
|
|
111
|
+
location: subject.location,
|
|
112
|
+
)
|
|
61
113
|
end
|
|
62
114
|
}
|
|
63
115
|
else
|
|
64
|
-
raise ReeMapper::TypeError
|
|
116
|
+
raise ReeMapper::TypeError.new("`#{name}` should be an array, got `#{truncate(value.inspect)}`", location)
|
|
65
117
|
end
|
|
66
118
|
end
|
|
67
|
-
end
|
|
119
|
+
end
|
|
@@ -14,6 +14,7 @@ module ReeMapper
|
|
|
14
14
|
|
|
15
15
|
require_relative 'ree_mapper/types/abstract_type'
|
|
16
16
|
require_relative 'ree_mapper/errors/error'
|
|
17
|
+
require_relative 'ree_mapper/errors/error_with_location'
|
|
17
18
|
require_relative 'ree_mapper/errors/coercion_error'
|
|
18
19
|
require_relative 'ree_mapper/errors/type_error'
|
|
19
20
|
require_relative 'ree_mapper/errors/unsupported_type_error'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require 'benchmark'
|
|
3
|
+
|
|
4
|
+
package_require "ree_mapper"
|
|
5
|
+
|
|
6
|
+
RSpec.xdescribe 'Mapper Benchmark' do
|
|
7
|
+
link :build_mapper_factory, from: :ree_mapper
|
|
8
|
+
link :build_mapper_strategy, from: :ree_mapper
|
|
9
|
+
|
|
10
|
+
let(:mapper) do
|
|
11
|
+
build_mapper_factory(
|
|
12
|
+
strategies: [
|
|
13
|
+
build_mapper_strategy(method: :cast, dto: Hash),
|
|
14
|
+
]
|
|
15
|
+
).call.use(:cast) do
|
|
16
|
+
hash :my_field do
|
|
17
|
+
hash :my_field do
|
|
18
|
+
integer :my_field
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it do
|
|
25
|
+
obj = { my_field: { my_field: { my_field: 1 } } }
|
|
26
|
+
|
|
27
|
+
_benchmark_res = Benchmark.bmbm do |x|
|
|
28
|
+
x.report('cast') { 1000.times { mapper.cast(obj) } }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -82,10 +82,12 @@ RSpec.describe ReeMapper::MapperFactory do
|
|
|
82
82
|
describe '.register_wrapper' do
|
|
83
83
|
let(:round_wrapper) {
|
|
84
84
|
Class.new(ReeMapper::AbstractWrapper) do
|
|
85
|
-
def serialize(value, name:, **opts)
|
|
86
|
-
|
|
85
|
+
def serialize(value, name:, location: nil, **opts)
|
|
86
|
+
if !value.is_a?(Numeric)
|
|
87
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a number, got `#{truncate(value.inspect)}`", location)
|
|
88
|
+
end
|
|
87
89
|
|
|
88
|
-
subject.type.serialize(value.round, name: name, **opts)
|
|
90
|
+
subject.type.serialize(value.round, name: name, location: subject.location, **opts)
|
|
89
91
|
end
|
|
90
92
|
end
|
|
91
93
|
}
|
|
@@ -100,10 +102,12 @@ RSpec.describe ReeMapper::MapperFactory do
|
|
|
100
102
|
|
|
101
103
|
it 'allow to register caster and serializer with the same name' do
|
|
102
104
|
caster_round_wrapper = Class.new(ReeMapper::AbstractWrapper) do
|
|
103
|
-
def cast(value, name:, **opts)
|
|
104
|
-
value = subject.type.cast(value, name: name, **opts)
|
|
105
|
+
def cast(value, name:, location: nil, **opts)
|
|
106
|
+
value = subject.type.cast(value, name: name, location: subject.location, **opts)
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
if !value.is_a?(Numeric)
|
|
109
|
+
raise ReeMapper::TypeError.new("`#{name}` should be a number, got `#{truncate(value.inspect)}`", location)
|
|
110
|
+
end
|
|
107
111
|
value.round
|
|
108
112
|
end
|
|
109
113
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
package_require "ree_mapper"
|
|
2
3
|
|
|
3
4
|
RSpec.describe ReeMapper::Mapper do
|
|
4
5
|
link :build_mapper_factory, from: :ree_mapper
|
|
@@ -32,6 +33,12 @@ RSpec.describe ReeMapper::Mapper do
|
|
|
32
33
|
obj.define_singleton_method(:my_field) { 1 }
|
|
33
34
|
expect(mapper.cast(obj)).to eq({ my_field: 1 })
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
it "add mapper location to error full message" do
|
|
38
|
+
mapper.cast({ my_field: "not number" })
|
|
39
|
+
rescue => e
|
|
40
|
+
expect(e.full_message).to include("located at")
|
|
41
|
+
end
|
|
35
42
|
end
|
|
36
43
|
|
|
37
44
|
describe 'hash dto' do
|
|
@@ -31,11 +31,11 @@ RSpec.describe 'ReeMapper::Bool' do
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
it {
|
|
34
|
-
expect { mapper.serialize({ bool: 'true' }) }.to raise_error(ReeMapper::TypeError,
|
|
34
|
+
expect { mapper.serialize({ bool: 'true' }) }.to raise_error(ReeMapper::TypeError, /`bool` should be a boolean, got `\"true\"`/)
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
it {
|
|
38
|
-
expect { mapper.serialize({ bool: 1 }) }.to raise_error(ReeMapper::TypeError,
|
|
38
|
+
expect { mapper.serialize({ bool: 1 }) }.to raise_error(ReeMapper::TypeError, /`bool` should be a boolean, got `1`/)
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -81,12 +81,12 @@ RSpec.describe 'ReeMapper::Bool' do
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
it {
|
|
84
|
-
expect { mapper.cast({ 'bool' => 'right' }) }.to raise_error(ReeMapper::CoercionError,
|
|
84
|
+
expect { mapper.cast({ 'bool' => 'right' }) }.to raise_error(ReeMapper::CoercionError, /`bool` is invalid boolean, got `\"right\"`/)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
it {
|
|
88
88
|
object = Object.new
|
|
89
|
-
expect { mapper.cast({ 'bool' => object }) }.to raise_error(ReeMapper::CoercionError,
|
|
89
|
+
expect { mapper.cast({ 'bool' => object }) }.to raise_error(ReeMapper::CoercionError, /`bool` is invalid boolean, got `#{object.inspect}`/)
|
|
90
90
|
}
|
|
91
91
|
end
|
|
92
92
|
|
|
@@ -100,11 +100,11 @@ RSpec.describe 'ReeMapper::Bool' do
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
it {
|
|
103
|
-
expect { mapper.db_dump(OpenStruct.new({ bool: 'true' })) }.to raise_error(ReeMapper::TypeError,
|
|
103
|
+
expect { mapper.db_dump(OpenStruct.new({ bool: 'true' })) }.to raise_error(ReeMapper::TypeError, /`bool` should be a boolean, got `\"true\"`/)
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
it {
|
|
107
|
-
expect { mapper.db_dump(OpenStruct.new({ bool: 1 })) }.to raise_error(ReeMapper::TypeError,
|
|
107
|
+
expect { mapper.db_dump(OpenStruct.new({ bool: 1 })) }.to raise_error(ReeMapper::TypeError, /`bool` should be a boolean, got `1`/)
|
|
108
108
|
}
|
|
109
109
|
end
|
|
110
110
|
|
|
@@ -150,12 +150,12 @@ RSpec.describe 'ReeMapper::Bool' do
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
it {
|
|
153
|
-
expect { mapper.db_load({ 'bool' => 'right' }) }.to raise_error(ReeMapper::CoercionError,
|
|
153
|
+
expect { mapper.db_load({ 'bool' => 'right' }) }.to raise_error(ReeMapper::CoercionError, /`bool` is invalid boolean, got `\"right\"`/)
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
it {
|
|
157
157
|
object = Object.new
|
|
158
|
-
expect { mapper.db_load({ 'bool' => object }) }.to raise_error(ReeMapper::CoercionError,
|
|
158
|
+
expect { mapper.db_load({ 'bool' => object }) }.to raise_error(ReeMapper::CoercionError, /`bool` is invalid boolean, got `#{object.inspect}`/)
|
|
159
159
|
}
|
|
160
160
|
end
|
|
161
161
|
end
|