smart_types 0.2.0 → 0.3.0

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/Gemfile.lock +33 -32
  4. data/README.md +161 -16
  5. data/lib/smart_core/types.rb +2 -0
  6. data/lib/smart_core/types/errors.rb +12 -0
  7. data/lib/smart_core/types/primitive.rb +49 -4
  8. data/lib/smart_core/types/primitive/caster.rb +5 -2
  9. data/lib/smart_core/types/primitive/checker.rb +5 -2
  10. data/lib/smart_core/types/primitive/factory.rb +64 -6
  11. data/lib/smart_core/types/primitive/factory/definition_context.rb +37 -11
  12. data/lib/smart_core/types/primitive/factory/runtime_type_builder.rb +53 -0
  13. data/lib/smart_core/types/primitive/invariant_control.rb +6 -3
  14. data/lib/smart_core/types/primitive/invariant_control/chain.rb +5 -2
  15. data/lib/smart_core/types/primitive/invariant_control/single.rb +5 -2
  16. data/lib/smart_core/types/primitive/mult_factory.rb +40 -6
  17. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +23 -1
  18. data/lib/smart_core/types/primitive/mult_validator.rb +8 -0
  19. data/lib/smart_core/types/primitive/nilable_factory.rb +10 -3
  20. data/lib/smart_core/types/primitive/runtime_attributes_checker.rb +77 -0
  21. data/lib/smart_core/types/primitive/sum_factory.rb +40 -6
  22. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +23 -1
  23. data/lib/smart_core/types/primitive/sum_validator.rb +18 -2
  24. data/lib/smart_core/types/primitive/undefined_caster.rb +4 -1
  25. data/lib/smart_core/types/primitive/validator.rb +16 -7
  26. data/lib/smart_core/types/protocol.rb +7 -0
  27. data/lib/smart_core/types/protocol/instance_of.rb +19 -0
  28. data/lib/smart_core/types/value/array.rb +3 -0
  29. data/lib/smart_core/types/value/big_decimal.rb +4 -1
  30. data/lib/smart_core/types/value/boolean.rb +3 -0
  31. data/lib/smart_core/types/value/class.rb +3 -0
  32. data/lib/smart_core/types/value/date.rb +3 -0
  33. data/lib/smart_core/types/value/date_time.rb +3 -0
  34. data/lib/smart_core/types/value/enumerable.rb +1 -1
  35. data/lib/smart_core/types/value/float.rb +3 -0
  36. data/lib/smart_core/types/value/hash.rb +3 -0
  37. data/lib/smart_core/types/value/integer.rb +3 -0
  38. data/lib/smart_core/types/value/module.rb +3 -0
  39. data/lib/smart_core/types/value/numeric.rb +3 -0
  40. data/lib/smart_core/types/value/proc.rb +3 -0
  41. data/lib/smart_core/types/value/set.rb +11 -3
  42. data/lib/smart_core/types/value/string.rb +3 -0
  43. data/lib/smart_core/types/value/string_io.rb +2 -0
  44. data/lib/smart_core/types/value/symbol.rb +3 -0
  45. data/lib/smart_core/types/value/text.rb +6 -4
  46. data/lib/smart_core/types/value/time.rb +3 -0
  47. data/lib/smart_core/types/value/time_based.rb +8 -5
  48. data/lib/smart_core/types/variadic.rb +7 -0
  49. data/lib/smart_core/types/variadic/tuple.rb +23 -0
  50. data/lib/smart_core/types/version.rb +2 -2
  51. data/smart_types.gemspec +3 -3
  52. metadata +15 -10
  53. data/.travis.yml +0 -21
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::InvariantControl
6
7
  require_relative 'invariant_control/result'
7
8
  require_relative 'invariant_control/single'
@@ -32,18 +33,20 @@ class SmartCore::Types::Primitive::InvariantControl
32
33
  end
33
34
 
34
35
  # @param value [Any]
36
+ # @param runtime_attributes [Array<Any>]
35
37
  # @return [SmartCore::Types::Primitive::InvariantControl::Result]
36
38
  #
37
39
  # @api private
38
40
  # @since 0.2.0
39
- def check(value)
41
+ # @version 0.3.0
42
+ def check(value, runtime_attributes)
40
43
  Result.new(self, value).tap do |result|
41
44
  invariant_chains.each do |chain|
42
- result.add_chain_result(chain.check(value))
45
+ result.add_chain_result(chain.check(value, runtime_attributes))
43
46
  end
44
47
 
45
48
  invariants.each do |invariant|
46
- result.add_single_result(invariant.check(value))
49
+ result.add_single_result(invariant.check(value, runtime_attributes))
47
50
  end
48
51
  end
49
52
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::InvariantControl::Chain
6
7
  require_relative 'chain/result'
7
8
 
@@ -31,14 +32,16 @@ class SmartCore::Types::Primitive::InvariantControl::Chain
31
32
  end
32
33
 
33
34
  # @param value [Any]
35
+ # @param runtime_attributes [Array<Any>]
34
36
  # @return [SmartCore::Types::Primitive::InvariantControl::Chain::Result]
35
37
  #
36
38
  # @api private
37
39
  # @since 0.2.0
38
- def check(value)
40
+ # @version 0.3.0
41
+ def check(value, runtime_attributes)
39
42
  invariant_results = [].tap do |results|
40
43
  invariants.each do |invariant|
41
- result = invariant.check(value).tap { |res| results << res }
44
+ result = invariant.check(value, runtime_attributes).tap { |res| results << res }
42
45
  break if result.failure?
43
46
  end
44
47
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::InvariantControl::Single
6
7
  require_relative 'single/result'
7
8
 
@@ -35,12 +36,14 @@ class SmartCore::Types::Primitive::InvariantControl::Single
35
36
  end
36
37
 
37
38
  # @param value [Any]
39
+ # @param runtime_attributes [Array<Any>]
38
40
  # @return [SmartCore::Types::Primitive::InvariantControl::Single::Result]
39
41
  #
40
42
  # @api private
41
43
  # @since 0.2.0
42
- def check(value)
43
- validation_result = !!invariant_checker.call(value)
44
+ # @version 0.3.0
45
+ def check(value, runtime_attributes)
46
+ validation_result = !!invariant_checker.call(value, runtime_attributes)
44
47
  Result.new(self, value, validation_result)
45
48
  end
46
49
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- # @version 0.2.0
5
+ # @version 0.3.0
6
6
  module SmartCore::Types::Primitive::MultFactory
7
7
  require_relative 'mult_factory/definition_context'
8
8
 
@@ -13,13 +13,19 @@ module SmartCore::Types::Primitive::MultFactory
13
13
  #
14
14
  # @api private
15
15
  # @since 0.1.0
16
- # @version 0.2.0
16
+ # @version 0.3.0
17
17
  def create_type(types, type_definition)
18
18
  type_definitions = build_type_definitions(type_definition)
19
+ type_runtime_attributes_checker = build_type_runtime_attributes_checker(type_definitions)
19
20
  type_validator = build_type_validator(types, type_definitions)
20
21
  type_caster = build_type_caster(types, type_definitions)
21
- build_type(type_validator, type_caster).tap do |type|
22
+ build_type(
23
+ type_validator,
24
+ type_caster,
25
+ type_runtime_attributes_checker
26
+ ).tap do |type|
22
27
  assign_type_validator(type, type_validator)
28
+ assign_type_runtime_attributes_checker(type, type_runtime_attributes_checker)
23
29
  end
24
30
  end
25
31
 
@@ -36,6 +42,17 @@ module SmartCore::Types::Primitive::MultFactory
36
42
  end
37
43
  end
38
44
 
45
+ # @param type_definitions [SmartCore::Types::Primitive::MultFactory::DefinitionContext]
46
+ # @return [SmartCore::Types::Primitive::RuntimeAttributesChecker]
47
+ #
48
+ # @api private
49
+ # @since 0.3.0
50
+ def build_type_runtime_attributes_checker(type_definitions)
51
+ SmartCore::Types::Primitive::RuntimeAttributesChecker.new(
52
+ type_definitions.type_runtime_attributes_checker
53
+ )
54
+ end
55
+
39
56
  # @param types [Array<SmartCore::Types::Primtive>]
40
57
  # @param type_definitions [SmartCore::Types::Primitive::MultFactory::DefinitionContext]
41
58
  # @return [SmartCore::Types::Primitive::MultValidator]
@@ -70,15 +87,32 @@ module SmartCore::Types::Primitive::MultFactory
70
87
  type_validator.___assign_type___(type)
71
88
  end
72
89
 
90
+ # @param type [SmartCore::Types::Primitive]
91
+ # @param type_runtime_attributes_checker [SmartCore::Types::Primitive::RuntimeAttributesChecker]
92
+ # @return [void]
93
+ #
94
+ # @api private
95
+ # @since 0.3.0
96
+ def assign_type_runtime_attributes_checker(type, type_runtime_attributes_checker)
97
+ type_runtime_attributes_checker.___assign_type___(type)
98
+ end
99
+
73
100
  # @param type_validator [SmartCore::Types::Primitive::MultValidator]
74
101
  # @param type_caster [SmartCore::Types::Primitive::Caster]
102
+ # @param type_runtime_attributes_checker [SmartCore::Types::Primitive::RuntimeAttributesChecker]
75
103
  # @return [SmartCore::Types::Primitive]
76
104
  #
77
105
  # @api private
78
106
  # @since 0.1.0
79
- # @version 0.2.0
80
- def build_type(type_validator, type_caster)
81
- SmartCore::Types::Primitive.new(nil, type_validator, type_caster)
107
+ # @version 0.3.0
108
+ def build_type(type_validator, type_caster, type_runtime_attributes_checker)
109
+ SmartCore::Types::Primitive.new(
110
+ nil,
111
+ nil,
112
+ type_validator,
113
+ type_caster,
114
+ type_runtime_attributes_checker
115
+ )
82
116
  end
83
117
  end
84
118
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::MultFactory::DefinitionContext
6
7
  # @return [Proc, NilClass]
7
8
  #
@@ -9,12 +10,20 @@ class SmartCore::Types::Primitive::MultFactory::DefinitionContext
9
10
  # @since 0.1.0
10
11
  attr_reader :type_caster
11
12
 
13
+ # @return [Proc, NilClass]
14
+ #
15
+ # @api private
16
+ # @since 0.3.0
17
+ attr_reader :type_runtime_attributes_checker
18
+
12
19
  # @return [void]
13
20
  #
14
21
  # @api private
15
22
  # @since 0.1.0
23
+ # @version 0.3.0
16
24
  def initialize
17
25
  @type_caster = nil
26
+ @type_runtime_attributes_checker = nil
18
27
  end
19
28
 
20
29
  # @param caster [Block]
@@ -22,10 +31,23 @@ class SmartCore::Types::Primitive::MultFactory::DefinitionContext
22
31
  #
23
32
  # @api public
24
33
  # @since 0.1.0
34
+ # @version 0.3.0
25
35
  def define_caster(&caster)
26
- raise(SmartCore::Types::ArgumentError, 'No caster definition block') unless block_given?
36
+ raise(SmartCore::Types::TypeDefinitionError, 'No caster definition block') unless block_given?
27
37
  @type_caster = caster
28
38
  end
29
39
 
40
+ # @param definition [Block]
41
+ # @return [void]
42
+ #
43
+ # @api public
44
+ # @since 0.3.0
45
+ def runtime_attributes_checker(&definition)
46
+ unless block_given?
47
+ raise(SmartCore::Types::TypeDefinitionError, 'No runtime checker definition block')
48
+ end
49
+ @type_runtime_attributes_checker = definition
50
+ end
51
+
30
52
  # TODO (0.x.0): invariant API
31
53
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::MultValidator < SmartCore::Types::Primitive::SumValidator
6
7
  require_relative 'mult_validator/result'
7
8
 
@@ -12,6 +13,13 @@ class SmartCore::Types::Primitive::MultValidator < SmartCore::Types::Primitive::
12
13
  # @api private
13
14
  # @since 0.2.0
14
15
 
16
+ # @overload ___copy_for___(type)
17
+ # @param type [SmartCore::Types::Primitive]
18
+ # @return [SmartCore::Types::Primitive::MultValidator]
19
+ #
20
+ # @api private
21
+ # @since 0.3.0
22
+
15
23
  private
16
24
 
17
25
  # @param validation [Block]
@@ -2,7 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- # @version 0.2.0
5
+ # @version 0.3.0
6
6
  module SmartCore::Types::Primitive::NilableFactory
7
7
  class << self
8
8
  # @param type [SmartCore::Types::Primitive]
@@ -56,9 +56,16 @@ module SmartCore::Types::Primitive::NilableFactory
56
56
  #
57
57
  # @api private
58
58
  # @since 0.1.0
59
- # @version 0.2.0
59
+ # @version 0.3.0
60
60
  def build_type(type, type_validator, type_caster)
61
- Class.new(type.class).new(type.name, type_validator, type_caster)
61
+ Class.new(type.class).new(
62
+ type.name,
63
+ type.category,
64
+ type_validator,
65
+ type_caster,
66
+ type.runtime_attributes_checker,
67
+ *type.runtime_attributes
68
+ )
62
69
  end
63
70
  end
64
71
  end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.3.0
5
+ class SmartCore::Types::Primitive::RuntimeAttributesChecker
6
+ # @return [Proc]
7
+ #
8
+ # @api private
9
+ # @since 0.3.0
10
+ ATTRIBUTES_IS_NOT_ALLOWED_CHECKER = proc do |attrs|
11
+ attrs.empty? || raise(SmartCore::Types::RuntimeAttriburtesUnsupportedError, <<~ERROR_MESSAGE)
12
+ This type has no support for runtime attributes.
13
+ ERROR_MESSAGE
14
+ end.freeze
15
+
16
+ # @param attributes_checker [Proc]
17
+ # @return [void]
18
+ #
19
+ # @api private
20
+ # @since 0.3.0
21
+ def initialize(attributes_checker)
22
+ @type = nil
23
+ @attributes_checker = attributes_checker || ATTRIBUTES_IS_NOT_ALLOWED_CHECKER
24
+ end
25
+
26
+ # @param type [SmartCore::Types::Primitive]
27
+ # @return [SmartCore::Types::Primitive::RuntimeAttributesChecker]
28
+ #
29
+ # @api private
30
+ # @since 0.3.0
31
+ def ___copy_for___(type)
32
+ self.class.new(attributes_checker).tap do |instance_copy|
33
+ instance_copy.___assign_type___(type)
34
+ end
35
+ end
36
+
37
+ # @param type [SmartCore::Types::Primitive]
38
+ # @return [void]
39
+ #
40
+ # @api private
41
+ # @since 0.3.0
42
+ def ___assign_type___(type)
43
+ @type = type
44
+ end
45
+
46
+ # @param runtime_attributes [Array<Any>]
47
+ # @return [void]
48
+ #
49
+ # @raise [SmartCore::Types::IncorrectRuntimeAttributesError]
50
+ #
51
+ # @api private
52
+ # @since 0.3.0
53
+ def check!(runtime_attributes)
54
+ unless !!attributes_checker.call(runtime_attributes)
55
+ # TODO (0.x.0):
56
+ # Full type name (with type category; and delegated to the type object).
57
+ # (main problem: sum and mult types has no type name and type category)
58
+ raise(SmartCore::Types::IncorrectRuntimeAttributesError, <<~ERROR_MESSAGE)
59
+ Incorrect runtime attributes for #{type.name}.
60
+ ERROR_MESSAGE
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ # @return [SmartCore::Types::Primitive]
67
+ #
68
+ # @api private
69
+ # @since 0.3.0
70
+ attr_reader :type
71
+
72
+ # @return [Proc]
73
+ #
74
+ # @api private
75
+ # @since 0.3.0
76
+ attr_reader :attributes_checker
77
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- # @version 0.2.0
5
+ # @version 0.3.0
6
6
  module SmartCore::Types::Primitive::SumFactory
7
7
  require_relative 'sum_factory/definition_context'
8
8
 
@@ -13,13 +13,19 @@ module SmartCore::Types::Primitive::SumFactory
13
13
  #
14
14
  # @api private
15
15
  # @since 0.1.0
16
- # @version 0.2.0
16
+ # @version 0.3.0
17
17
  def create_type(types, type_definition)
18
18
  type_definitions = build_type_definitions(type_definition)
19
+ type_runtime_attributes_checker = build_type_runtime_attributes_checker(type_definitions)
19
20
  type_validator = build_type_validator(types, type_definitions)
20
21
  type_caster = build_type_caster(types, type_definitions)
21
- build_type(type_validator, type_caster).tap do |type|
22
+ build_type(
23
+ type_validator,
24
+ type_caster,
25
+ type_runtime_attributes_checker
26
+ ).tap do |type|
22
27
  assign_type_validator(type, type_validator)
28
+ assign_type_runtime_attributes_checker(type, type_runtime_attributes_checker)
23
29
  end
24
30
  end
25
31
 
@@ -36,6 +42,17 @@ module SmartCore::Types::Primitive::SumFactory
36
42
  end
37
43
  end
38
44
 
45
+ # @param type_definitions [SmartCore::Types::Primitive::SumFactory::DefinitionContext]
46
+ # @return [SmartCore::Types::Primitive::RuntimeAttributesChecker]
47
+ #
48
+ # @api private
49
+ # @since 0.3.0
50
+ def build_type_runtime_attributes_checker(type_definitions)
51
+ SmartCore::Types::Primitive::RuntimeAttributesChecker.new(
52
+ type_definitions.type_runtime_attributes_checker
53
+ )
54
+ end
55
+
39
56
  # @param types [Array<SmartCore::Types::Primtive>]
40
57
  # @param type_definitions [SmartCore::Types::Primitive::SumFactory::DefinitionContext]
41
58
  # @return [SmartCore::Types::Primitive::SumValidator]
@@ -70,15 +87,32 @@ module SmartCore::Types::Primitive::SumFactory
70
87
  type_validator.___assign_type___(type)
71
88
  end
72
89
 
90
+ # @param type [SmartCore::Types::Primitive]
91
+ # @param type_runtime_attributes_checker [SmartCore::Types::Primitive::RuntimeAttributesChecker]
92
+ # @return [void]
93
+ #
94
+ # @api private
95
+ # @since 0.3.0
96
+ def assign_type_runtime_attributes_checker(type, type_runtime_attributes_checker)
97
+ type_runtime_attributes_checker.___assign_type___(type)
98
+ end
99
+
73
100
  # @param type_validator [SmartCore::Types::Primitive::SumValidator)]
74
101
  # @param type_caster [SmartCore::Types::Primitive::Caster]
102
+ # @param type_runtime_attributes_checker [SmartCore::Types::Primitive::RuntimeAttributesChecker]
75
103
  # @return [SmartCore::Types::Primitive]
76
104
  #
77
105
  # @api private
78
106
  # @since 0.1.0
79
- # @version 0.2.0
80
- def build_type(type_validator, type_caster)
81
- SmartCore::Types::Primitive.new(nil, type_validator, type_caster)
107
+ # @version 0.3.0
108
+ def build_type(type_validator, type_caster, type_runtime_attributes_checker)
109
+ SmartCore::Types::Primitive.new(
110
+ nil,
111
+ nil,
112
+ type_validator,
113
+ type_caster,
114
+ type_runtime_attributes_checker
115
+ )
82
116
  end
83
117
  end
84
118
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::SumFactory::DefinitionContext
6
7
  # @return [Proc, NilClass]
7
8
  #
@@ -9,12 +10,20 @@ class SmartCore::Types::Primitive::SumFactory::DefinitionContext
9
10
  # @since 0.1.0
10
11
  attr_reader :type_caster
11
12
 
13
+ # @return [Proc, NilClass]
14
+ #
15
+ # @api private
16
+ # @since 0.3.0
17
+ attr_reader :type_runtime_attributes_checker
18
+
12
19
  # @return [void]
13
20
  #
14
21
  # @api private
15
22
  # @since 0.1.0
23
+ # @version 0.3.0
16
24
  def initialize
17
25
  @type_caster = nil
26
+ @type_runtime_attributes_checker = nil
18
27
  end
19
28
 
20
29
  # @param caster [Block]
@@ -22,10 +31,23 @@ class SmartCore::Types::Primitive::SumFactory::DefinitionContext
22
31
  #
23
32
  # @api public
24
33
  # @since 0.1.0
34
+ # @version 0.3.0
25
35
  def define_caster(&caster)
26
- raise(SmartCore::Types::ArgumentError, 'No caster definition block') unless block_given?
36
+ raise(SmartCore::Types::TypeDefinitionError, 'No caster definition block') unless block_given?
27
37
  @type_caster = caster
28
38
  end
29
39
 
40
+ # @param definition [Block]
41
+ # @return [void]
42
+ #
43
+ # @api public
44
+ # @since 0.3.0
45
+ def runtime_attributes_checker(&definition)
46
+ unless block_given?
47
+ raise(SmartCore::Types::TypeDefinitionError, 'No runtime checker definition block')
48
+ end
49
+ @type_runtime_attributes_checker = definition
50
+ end
51
+
30
52
  # TODO (0.x.0): invariant API
31
53
  end