smart_types 0.1.0.alpha5 → 0.4.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/CHANGELOG.md +46 -0
  4. data/Gemfile.lock +80 -52
  5. data/README.md +437 -27
  6. data/Rakefile +1 -1
  7. data/bin/console +2 -2
  8. data/lib/smart_core/types.rb +2 -0
  9. data/lib/smart_core/types/errors.rb +16 -0
  10. data/lib/smart_core/types/primitive.rb +109 -24
  11. data/lib/smart_core/types/primitive/caster.rb +5 -2
  12. data/lib/smart_core/types/primitive/checker.rb +5 -2
  13. data/lib/smart_core/types/primitive/factory.rb +105 -8
  14. data/lib/smart_core/types/primitive/factory/definition_context.rb +142 -6
  15. data/lib/smart_core/types/primitive/factory/runtime_type_builder.rb +53 -0
  16. data/lib/smart_core/types/primitive/invariant_control.rb +67 -0
  17. data/lib/smart_core/types/primitive/invariant_control/chain.rb +61 -0
  18. data/lib/smart_core/types/primitive/invariant_control/chain/result.rb +64 -0
  19. data/lib/smart_core/types/primitive/invariant_control/factory.rb +54 -0
  20. data/lib/smart_core/types/primitive/invariant_control/factory/chain_definition_context.rb +39 -0
  21. data/lib/smart_core/types/primitive/invariant_control/result.rb +104 -0
  22. data/lib/smart_core/types/primitive/invariant_control/single.rb +57 -0
  23. data/lib/smart_core/types/primitive/invariant_control/single/result.rb +63 -0
  24. data/lib/smart_core/types/primitive/mult_factory.rb +59 -10
  25. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +27 -3
  26. data/lib/smart_core/types/primitive/mult_validator.rb +42 -0
  27. data/lib/smart_core/types/primitive/mult_validator/result.rb +8 -0
  28. data/lib/smart_core/types/primitive/nilable_factory.rb +31 -9
  29. data/lib/smart_core/types/primitive/nilable_validator.rb +83 -0
  30. data/lib/smart_core/types/primitive/nilable_validator/result.rb +78 -0
  31. data/lib/smart_core/types/primitive/runtime_attributes_checker.rb +77 -0
  32. data/lib/smart_core/types/primitive/sum_factory.rb +59 -10
  33. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +26 -2
  34. data/lib/smart_core/types/primitive/sum_validator.rb +117 -0
  35. data/lib/smart_core/types/primitive/sum_validator/result.rb +100 -0
  36. data/lib/smart_core/types/primitive/undefined_caster.rb +7 -5
  37. data/lib/smart_core/types/primitive/validator.rb +93 -0
  38. data/lib/smart_core/types/primitive/validator/result.rb +78 -0
  39. data/lib/smart_core/types/protocol.rb +7 -0
  40. data/lib/smart_core/types/protocol/instance_of.rb +19 -0
  41. data/lib/smart_core/types/system.rb +21 -5
  42. data/lib/smart_core/types/value.rb +16 -0
  43. data/lib/smart_core/types/value/array.rb +3 -0
  44. data/lib/smart_core/types/value/big_decimal.rb +31 -0
  45. data/lib/smart_core/types/value/boolean.rb +3 -0
  46. data/lib/smart_core/types/value/class.rb +3 -0
  47. data/lib/smart_core/types/value/comparable.rb +13 -0
  48. data/lib/smart_core/types/value/date.rb +24 -0
  49. data/lib/smart_core/types/value/date_time.rb +24 -0
  50. data/lib/smart_core/types/value/enumerable.rb +13 -0
  51. data/lib/smart_core/types/value/enumerator.rb +13 -0
  52. data/lib/smart_core/types/value/enumerator_chain.rb +13 -0
  53. data/lib/smart_core/types/value/float.rb +9 -2
  54. data/lib/smart_core/types/value/hash.rb +11 -1
  55. data/lib/smart_core/types/value/integer.rb +13 -3
  56. data/lib/smart_core/types/value/io.rb +13 -0
  57. data/lib/smart_core/types/value/method.rb +9 -0
  58. data/lib/smart_core/types/value/module.rb +3 -0
  59. data/lib/smart_core/types/value/nil.rb +3 -3
  60. data/lib/smart_core/types/value/numeric.rb +16 -3
  61. data/lib/smart_core/types/value/proc.rb +14 -1
  62. data/lib/smart_core/types/value/range.rb +9 -0
  63. data/lib/smart_core/types/value/rational.rb +13 -0
  64. data/lib/smart_core/types/value/set.rb +21 -0
  65. data/lib/smart_core/types/value/string.rb +10 -1
  66. data/lib/smart_core/types/value/string_io.rb +15 -0
  67. data/lib/smart_core/types/value/symbol.rb +10 -1
  68. data/lib/smart_core/types/value/text.rb +21 -4
  69. data/lib/smart_core/types/value/time.rb +24 -0
  70. data/lib/smart_core/types/value/time_based.rb +32 -0
  71. data/lib/smart_core/types/value/unbound_method.rb +9 -0
  72. data/lib/smart_core/types/variadic.rb +7 -0
  73. data/lib/smart_core/types/variadic/tuple.rb +23 -0
  74. data/lib/smart_core/types/version.rb +2 -2
  75. data/smart_types.gemspec +6 -5
  76. metadata +69 -23
  77. data/.travis.yml +0 -20
  78. data/lib/smart_core/types/primitive/mult_checker.rb +0 -31
  79. data/lib/smart_core/types/primitive/nilable_checker.rb +0 -37
  80. data/lib/smart_core/types/primitive/sum_checker.rb +0 -31
  81. data/lib/smart_core/types/system/definition_dsl.rb +0 -40
  82. data/lib/smart_core/types/system/producer_dsl.rb +0 -30
@@ -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
@@ -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
@@ -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::UndefinedCaster < SmartCore::Types::Primitive::Caster
6
7
  # @param expression [NilClass, Any]
7
8
  # @return [void]
@@ -13,16 +14,17 @@ class SmartCore::Types::Primitive::UndefinedCaster < SmartCore::Types::Primitive
13
14
  end
14
15
 
15
16
  # @param value [Any]
17
+ # @param runtime_attributes [Array<Any>]
16
18
  # @return [void]
17
19
  #
18
- # @raise [SmartCore::Types::TypeCastingError]
20
+ # @raise [SmartCore::Types::TypeCastingUnsupportedError]
19
21
  #
20
22
  # @pai private
21
23
  # @since 0.1.0
22
- def call(value)
23
- raise(
24
- SmartCore::Types::TypeCastingError,
24
+ # @version 0.3.0
25
+ def call(value, runtime_attributes)
26
+ raise(SmartCore::Types::TypeCastingUnsupportedError, <<~ERROR_MESSAGE)
25
27
  'This type has no support for type casting'
26
- )
28
+ ERROR_MESSAGE
27
29
  end
28
30
  end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ # @version 0.3.0
6
+ class SmartCore::Types::Primitive::Validator
7
+ require_relative 'validator/result'
8
+
9
+ # @return [SmartCore::Type::Primitive]
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ attr_reader :type
14
+
15
+ # @return [SmartCore::Types::Primitive::Checker]
16
+ #
17
+ # @api private
18
+ # @since 0.2.0
19
+ attr_reader :type_checker
20
+
21
+ # @return [SmartCore::Types::Primitive::InvariantControl]
22
+ #
23
+ # @api private
24
+ # @since 0.2.0
25
+ attr_reader :invariant_control
26
+
27
+ # @param type_checker [SmartCore::Types::Primitive::Checker]
28
+ # @param invariant_control [SmartCore::Types::Primitive::InvariantControl]
29
+ # @return [void]
30
+ #
31
+ # @api private
32
+ # @since 0.2.0
33
+ def initialize(type_checker, invariant_control)
34
+ @type = nil
35
+ @type_checker = type_checker
36
+ @invariant_control = invariant_control
37
+ end
38
+
39
+ # @param type [SmartCore::Types::Primitive]
40
+ # @return [SmartCore::Types::Primitive::Validator]
41
+ #
42
+ # @api private
43
+ # @since 0.3.0
44
+ def ___copy_for___(type)
45
+ self.class.new(type_checker, invariant_control).tap do |instance_copy|
46
+ instance_copy.___assign_type___(type)
47
+ end
48
+ end
49
+
50
+ # @param type [SmartCore::Types::Primitive]
51
+ # @return [void]
52
+ #
53
+ # @api private
54
+ # @since 0.2.0
55
+ def ___assign_type___(type)
56
+ @type = type
57
+ end
58
+
59
+ # @param value [Any]
60
+ # @return [Boolean]
61
+ #
62
+ # @api private
63
+ # @since 0.2.0
64
+ def valid?(value)
65
+ validate(value).success?
66
+ end
67
+
68
+ # @param value [Any]
69
+ # @return [SmartCore::Types::Primitive::Validator::Result]
70
+ #
71
+ # @api private
72
+ # @since 0.2.0
73
+ # @version 0.3.0
74
+ def validate(value)
75
+ checker_result = type_checker.call(value, type.runtime_attributes) # => Boolean
76
+ return Result.new(type, value, checker_result) unless checker_result
77
+ invariant_result = invariant_control.check(value, type.runtime_attributes)
78
+ invariant_errors = invariant_result.invariant_errors.map { |error| "#{type.name}.#{error}" }
79
+ Result.new(type, value, checker_result, invariant_errors)
80
+ end
81
+
82
+ # @param value [Any]
83
+ # @return [void]
84
+ #
85
+ # @raise [SmartCore::Types::TypeError]
86
+ #
87
+ # @api private
88
+ # @since 0.2.0
89
+ def validate!(value)
90
+ return if validate(value).success?
91
+ raise(SmartCore::Types::TypeError, 'Invalid type')
92
+ end
93
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::Validator::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 [Boolean]
19
+ #
20
+ # @api public
21
+ # @since 0.2.0
22
+ attr_reader :is_valid_check
23
+ alias_method :valid_check?, :is_valid_check
24
+
25
+ # @return [Any]
26
+ #
27
+ # @api public
28
+ # @since 0.2.0
29
+ attr_reader :checked_value
30
+ alias_method :value, :checked_value
31
+
32
+ # @return [Array<String>]
33
+ #
34
+ # @api public
35
+ # @since 0.2.0
36
+ attr_reader :invariant_errors
37
+ alias_method :errors, :invariant_errors
38
+ alias_method :error_codes, :invariant_errors
39
+
40
+ # @param type [SmartCore::Types::Primitive]
41
+ # @param checked_value [Any]
42
+ # @param is_valid_check [Boolean]
43
+ # @param invariant_errors [Array<String>]
44
+ # @return [void]
45
+ #
46
+ # @api private
47
+ # @since 0.2.0
48
+ def initialize(type, checked_value, is_valid_check, invariant_errors = NO_INVARIANT_ERRORS.dup)
49
+ @type = type
50
+ @checked_value = checked_value
51
+ @is_valid_check = is_valid_check
52
+ @invariant_errors = invariant_errors.tap(&:freeze)
53
+ end
54
+
55
+ # @return [Boolean]
56
+ #
57
+ # @api public
58
+ # @since 0.2.0
59
+ def valid_invariants?
60
+ invariant_errors.empty?
61
+ end
62
+
63
+ # @return [Boolean]
64
+ #
65
+ # @api public
66
+ # @since 0.2.0
67
+ def success?
68
+ valid_check? && invariant_errors.empty?
69
+ end
70
+
71
+ # @return [Boolean]
72
+ #
73
+ # @api public
74
+ # @since 0.2.0
75
+ def failure?
76
+ !success?
77
+ end
78
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.3.0
5
+ class SmartCore::Types::Protocol < SmartCore::Types::Primitive
6
+ require_relative 'protocol/instance_of'
7
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
5
+ # @api public
6
+ # @since 0.3.0
7
+ SmartCore::Types::Protocol.define_type(:InstanceOf) do |type|
8
+ type.runtime_attributes_checker do |runtime_attrs|
9
+ runtime_attrs.any? && runtime_attrs.all? do |runtime_attr|
10
+ runtime_attr.is_a?(::Class)
11
+ end
12
+ end
13
+
14
+ type.define_checker do |value, expected_types|
15
+ expected_types.any? && expected_types.any? do |expected_type|
16
+ value.is_a?(expected_type)
17
+ end
18
+ end
19
+ end