smart_types 0.1.0 → 0.6.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/CHANGELOG.md +57 -0
  4. data/Gemfile.lock +71 -58
  5. data/LICENSE.txt +1 -1
  6. data/README.md +363 -34
  7. data/Rakefile +0 -1
  8. data/bin/console +2 -2
  9. data/lib/smart_core/types/errors.rb +12 -0
  10. data/lib/smart_core/types/primitive/caster.rb +5 -2
  11. data/lib/smart_core/types/primitive/checker.rb +5 -2
  12. data/lib/smart_core/types/primitive/factory/definition_context.rb +140 -4
  13. data/lib/smart_core/types/primitive/factory/runtime_type_builder.rb +53 -0
  14. data/lib/smart_core/types/primitive/factory.rb +104 -7
  15. data/lib/smart_core/types/primitive/invariant_control/chain/result.rb +64 -0
  16. data/lib/smart_core/types/primitive/invariant_control/chain.rb +61 -0
  17. data/lib/smart_core/types/primitive/invariant_control/factory/chain_definition_context.rb +39 -0
  18. data/lib/smart_core/types/primitive/invariant_control/factory.rb +54 -0
  19. data/lib/smart_core/types/primitive/invariant_control/result.rb +104 -0
  20. data/lib/smart_core/types/primitive/invariant_control/single/result.rb +63 -0
  21. data/lib/smart_core/types/primitive/invariant_control/single.rb +57 -0
  22. data/lib/smart_core/types/primitive/invariant_control.rb +67 -0
  23. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +26 -2
  24. data/lib/smart_core/types/primitive/mult_factory.rb +59 -10
  25. data/lib/smart_core/types/primitive/mult_validator/result.rb +8 -0
  26. data/lib/smart_core/types/primitive/mult_validator.rb +42 -0
  27. data/lib/smart_core/types/primitive/nilable_factory.rb +31 -9
  28. data/lib/smart_core/types/primitive/nilable_validator/result.rb +78 -0
  29. data/lib/smart_core/types/primitive/nilable_validator.rb +83 -0
  30. data/lib/smart_core/types/primitive/runtime_attributes_checker.rb +77 -0
  31. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +25 -1
  32. data/lib/smart_core/types/primitive/sum_factory.rb +59 -10
  33. data/lib/smart_core/types/primitive/sum_validator/result.rb +100 -0
  34. data/lib/smart_core/types/primitive/sum_validator.rb +117 -0
  35. data/lib/smart_core/types/primitive/undefined_caster.rb +4 -1
  36. data/lib/smart_core/types/primitive/validator/result.rb +78 -0
  37. data/lib/smart_core/types/primitive/validator.rb +93 -0
  38. data/lib/smart_core/types/primitive.rb +99 -15
  39. data/lib/smart_core/types/protocol/instance_of.rb +19 -0
  40. data/lib/smart_core/types/protocol.rb +7 -0
  41. data/lib/smart_core/types/value/array.rb +3 -0
  42. data/lib/smart_core/types/value/big_decimal.rb +4 -1
  43. data/lib/smart_core/types/value/boolean.rb +3 -0
  44. data/lib/smart_core/types/value/class.rb +3 -0
  45. data/lib/smart_core/types/value/date.rb +3 -0
  46. data/lib/smart_core/types/value/date_time.rb +3 -0
  47. data/lib/smart_core/types/value/enumerable.rb +1 -1
  48. data/lib/smart_core/types/value/enumerator.rb +13 -0
  49. data/lib/smart_core/types/value/enumerator_chain.rb +13 -0
  50. data/lib/smart_core/types/value/float.rb +3 -0
  51. data/lib/smart_core/types/value/hash.rb +3 -0
  52. data/lib/smart_core/types/value/integer.rb +3 -0
  53. data/lib/smart_core/types/value/io.rb +13 -0
  54. data/lib/smart_core/types/value/method.rb +9 -0
  55. data/lib/smart_core/types/value/module.rb +3 -0
  56. data/lib/smart_core/types/value/nil.rb +0 -2
  57. data/lib/smart_core/types/value/numeric.rb +3 -0
  58. data/lib/smart_core/types/value/proc.rb +3 -0
  59. data/lib/smart_core/types/value/range.rb +9 -0
  60. data/lib/smart_core/types/value/rational.rb +13 -0
  61. data/lib/smart_core/types/value/set.rb +21 -0
  62. data/lib/smart_core/types/value/string.rb +3 -0
  63. data/lib/smart_core/types/value/string_io.rb +15 -0
  64. data/lib/smart_core/types/value/symbol.rb +3 -0
  65. data/lib/smart_core/types/value/text.rb +6 -4
  66. data/lib/smart_core/types/value/time.rb +3 -0
  67. data/lib/smart_core/types/value/time_based.rb +8 -5
  68. data/lib/smart_core/types/value/unbound_method.rb +9 -0
  69. data/lib/smart_core/types/value.rb +9 -0
  70. data/lib/smart_core/types/variadic/array_of.rb +23 -0
  71. data/lib/smart_core/types/variadic/enum.rb +11 -0
  72. data/lib/smart_core/types/variadic/tuple.rb +23 -0
  73. data/lib/smart_core/types/variadic.rb +10 -0
  74. data/lib/smart_core/types/version.rb +2 -1
  75. data/lib/smart_core/types.rb +2 -0
  76. data/smart_types.gemspec +5 -4
  77. metadata +61 -18
  78. data/.travis.yml +0 -21
  79. data/lib/smart_core/types/primitive/mult_checker.rb +0 -31
  80. data/lib/smart_core/types/primitive/nilable_checker.rb +0 -37
  81. data/lib/smart_core/types/primitive/sum_checker.rb +0 -31
@@ -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,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,8 +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::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
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
+
52
+ # TODO (0.x.0): invariant API
29
53
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # @version 0.3.0
5
6
  module SmartCore::Types::Primitive::SumFactory
6
7
  require_relative 'sum_factory/definition_context'
7
8
 
@@ -12,11 +13,20 @@ module SmartCore::Types::Primitive::SumFactory
12
13
  #
13
14
  # @api private
14
15
  # @since 0.1.0
16
+ # @version 0.3.0
15
17
  def create_type(types, type_definition)
16
18
  type_definitions = build_type_definitions(type_definition)
17
- type_checker = build_type_checker(types, type_definitions)
19
+ type_runtime_attributes_checker = build_type_runtime_attributes_checker(type_definitions)
20
+ type_validator = build_type_validator(types, type_definitions)
18
21
  type_caster = build_type_caster(types, type_definitions)
19
- build_type(type_checker, type_caster)
22
+ build_type(
23
+ type_validator,
24
+ type_caster,
25
+ type_runtime_attributes_checker
26
+ ).tap do |type|
27
+ assign_type_validator(type, type_validator)
28
+ assign_type_runtime_attributes_checker(type, type_runtime_attributes_checker)
29
+ end
20
30
  end
21
31
 
22
32
  private
@@ -32,14 +42,25 @@ module SmartCore::Types::Primitive::SumFactory
32
42
  end
33
43
  end
34
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
+
35
56
  # @param types [Array<SmartCore::Types::Primtive>]
36
57
  # @param type_definitions [SmartCore::Types::Primitive::SumFactory::DefinitionContext]
37
- # @return [SmartCore::Types::Primitive::SumChecker]
58
+ # @return [SmartCore::Types::Primitive::SumValidator]
38
59
  #
39
60
  # @api private
40
- # @since 0.1.0
41
- def build_type_checker(types, type_definitions)
42
- SmartCore::Types::Primitive::SumChecker.new(*types.map(&:checker))
61
+ # @since 0.2.0
62
+ def build_type_validator(types, type_definitions)
63
+ SmartCore::Types::Primitive::SumValidator.new(*types.map(&:validator))
43
64
  end
44
65
 
45
66
  # @param types [Array<SmartCore::Types::Primtive>]
@@ -49,21 +70,49 @@ module SmartCore::Types::Primitive::SumFactory
49
70
  # @api private
50
71
  # @since 0.1.0
51
72
  def build_type_caster(types, type_definitions)
52
- if type_definitions.type_caster.nil?
73
+ if type_definitions.type_caster == nil
53
74
  SmartCore::Types::Primitive::UndefinedCaster.new
54
75
  else
55
76
  SmartCore::Types::Primitive::Caster.new(type_definitions.type_caster)
56
77
  end
57
78
  end
58
79
 
59
- # @param type_checker [SmartCore::Types::Primitive::SumChecker]
80
+ # @param type [SmartCore::Types::Primitive]
81
+ # @param type_validator [SmartCore::Types::Primitive::SumValidator]
82
+ # @return [void]
83
+ #
84
+ # @api private
85
+ # @since 0.2.0
86
+ def assign_type_validator(type, type_validator)
87
+ type_validator.___assign_type___(type)
88
+ end
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
+
100
+ # @param type_validator [SmartCore::Types::Primitive::SumValidator)]
60
101
  # @param type_caster [SmartCore::Types::Primitive::Caster]
102
+ # @param type_runtime_attributes_checker [SmartCore::Types::Primitive::RuntimeAttributesChecker]
61
103
  # @return [SmartCore::Types::Primitive]
62
104
  #
63
105
  # @api private
64
106
  # @since 0.1.0
65
- def build_type(type_checker, type_caster)
66
- SmartCore::Types::Primitive.new(type_checker, 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
+ )
67
116
  end
68
117
  end
69
118
  end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::SumValidator::Result
6
+ # @return [Array]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ NO_INVARIANT_ERRORS = [].freeze
11
+
12
+ # @return [SmartCore::Types::Primitive]
13
+ #
14
+ # @api public
15
+ # @since 0.2.0
16
+ attr_reader :type
17
+
18
+ # @return concrete_validation_result [
19
+ # SmartCore::Types::Primitive::Validator::Result,
20
+ # SmartCore::Types::Primitive::SumValidator::Result,
21
+ # SmartCore::Types::Primitive::MultValidator::Result,
22
+ # SmartCore::Types::Primitive::NilableValidator::Result
23
+ # ]
24
+ #
25
+ # @api private
26
+ # @since 0.2.0
27
+ attr_reader :concrete_validation_result
28
+
29
+ # @return [Array<String>]
30
+ #
31
+ # @api public
32
+ # @since 0.2.0
33
+ attr_reader :invariant_errors
34
+ alias_method :errors, :invariant_errors
35
+ alias_method :error_codes, :invariant_errors
36
+
37
+ # @param type [SmartCore::Types::Primitive]
38
+ # @param concrete_validation_result [
39
+ # Boolean, (TEMPORARY)
40
+ # SmartCore::Types::Primitive::Validator::Result,
41
+ # SmartCore::Types::Primitive::SumValidator::Result,
42
+ # SmartCore::Types::Primitive::MultValidator::Result,
43
+ # SmartCore::Types::Primitive::NilableValidator::Result
44
+ # ]
45
+ # @param invariant_errors [Array<String>]
46
+ # @return [void]
47
+ #
48
+ # @api private
49
+ # @since 0.2.0
50
+ def initialize(type, concrete_validation_result, invariant_errors = NO_INVARIANT_ERRORS.dup)
51
+ @type = type
52
+ @concrete_validation_result = concrete_validation_result
53
+ @invariant_errors = invariant_errors.dup.tap(&:freeze)
54
+ end
55
+
56
+ # @return [Boolean]
57
+ #
58
+ # @api public
59
+ # @since 0.2.0
60
+ def valid_invariants?
61
+ # NOTE: at this moment type sum does not support invariant checking
62
+ # TODO (0.x.0):
63
+ # concrete_validation_result.valid_invariants?
64
+ true
65
+ end
66
+
67
+ # @return [Boolean]
68
+ #
69
+ # @api public
70
+ # @since 0.2.0
71
+ def is_valid_check
72
+ # NOTE: at this moment type sum does not support invariant checking
73
+ # TODO (0.x.0):
74
+ # concrete_validation_result.is_valid_check
75
+ concrete_validation_result
76
+ end
77
+ alias_method :valid_check?, :is_valid_check
78
+
79
+ # @return [Boolean]
80
+ #
81
+ # @api public
82
+ # @since 0.2.0
83
+ def success?
84
+ # NOTE: at this moment type sum does not support invariant checking
85
+ # TODO (0.x.0):
86
+ # concrete_validation_result.success?
87
+ concrete_validation_result
88
+ end
89
+
90
+ # @return [Boolean]
91
+ #
92
+ # @api public
93
+ # @since 0.2.0
94
+ def failure?
95
+ # NOTE: at this moment type sum does not support invariant checking
96
+ # TODO (0.x.0):
97
+ # concrete_validation_result.failure?
98
+ !success?
99
+ end
100
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ # @version 0.3.0
6
+ class SmartCore::Types::Primitive::SumValidator
7
+ require_relative 'sum_validator/result'
8
+
9
+ # @param validators [Array<SmartCore::Types::Primitive::Validator>]
10
+ # @return [void]
11
+ #
12
+ # @api private
13
+ # @since 0.2.0
14
+ def initialize(*validators)
15
+ @type = nil
16
+ @validators = validators
17
+ end
18
+
19
+ # @param type [SmartCore::Types::Primitive]
20
+ # @return [SmartCore::Types::Primitive::SumValidator]
21
+ #
22
+ # @api private
23
+ # @since 0.3.0
24
+ def ___copy_for___(type)
25
+ self.class.new(type_checker, invariant_control).tap do |instance_copy|
26
+ instance_copy.___assign_type___(type)
27
+ end
28
+ end
29
+
30
+ # @param type [SmartCore::Types::Primitive]
31
+ # @return [void]
32
+ #
33
+ # @api private
34
+ # @since 0.2.0
35
+ def ___assign_type___(type)
36
+ @type = type
37
+ end
38
+
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ # @since 0.2.0
43
+ # @version 0.3.0
44
+ def valid?(value)
45
+ # NOTE: at this moment type sum does not support invariant checking
46
+ # TODO (0.x.0):
47
+ # validators.any? { |validator| validator.valid?(value) }
48
+ validators.any? do |validator|
49
+ validator.type_checker.call(value, type.runtime_attributes)
50
+ end
51
+ end
52
+
53
+ # @param value [Any]
54
+ # @return [SmartCore::Types::Primitive::SumValidator::Result]
55
+ #
56
+ # @api private
57
+ # @since 0.2.0
58
+ # @version 0.3.0
59
+ def validate(value)
60
+ compile_validation_result do
61
+ SmartCore::Engine::Atom.new.tap do |result|
62
+ validators.each do |validator|
63
+ # NOTE: at this moment type sum does not support invariant checking
64
+ # TODO (0.x.0):
65
+ # result.swap { validator.validate(value) }
66
+ # break if result.value.success?
67
+ result.swap { validator.type_checker.call(value, type.runtime_attributes) }
68
+ break if result.value # => boolean
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ # @param value [Any]
75
+ # @return [void]
76
+ #
77
+ # @raise [SmartCore::Types::TypeError]
78
+ #
79
+ # @api private
80
+ # @since 0.2.0
81
+ def validate!(value)
82
+ return if valid?(value)
83
+ raise(SmartCore::Types::TypeError, 'Invalid type')
84
+ end
85
+
86
+ private
87
+
88
+ # @return [SmartCore::Types::Primitive]
89
+ #
90
+ # @api private
91
+ # @since 0.2.0
92
+ attr_reader :type
93
+
94
+ # @return [Array<SmartCore::Types::Primitive::Validator>]
95
+ #
96
+ # @api private
97
+ # @since 0.2.0
98
+ attr_reader :validators
99
+
100
+ # @param validation [Block]
101
+ # @yieldparam [void]
102
+ # @yieldreturn [SmartCore::Engine::Atom]
103
+ # @return [SmartCore::Types::Primitive::SumValidator::Result]
104
+ #
105
+ # @api private
106
+ # @since 0.2.0
107
+ def compile_validation_result(&validation)
108
+ # NOTE: at this moment type sum does not support invariant checking
109
+ # TODO (0.x.0):
110
+ # @yieldreturn [SmartCore::Types::Primitive::Validator::Result]
111
+ # => and:
112
+ # SmartCore::Types::Primitive::SumValidator::Result.new(
113
+ # type, final_result.value, final_result.value.invariant_errors
114
+ # )
115
+ SmartCore::Types::Primitive::SumValidator::Result.new(type, yield.value)
116
+ end
117
+ end