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,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Chain::Result
6
+ # @return [SmartCore::Types::Primitive::invariantControl::Chain]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :invariant_chain
11
+
12
+ # @return [Any]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ attr_reader :checked_value
17
+
18
+ # @param invariant_chain [SmartCore::Types::Primitive::invariantControl::Chain]
19
+ # @param checked_value [Any]
20
+ # @param invariant_results [Array<SmartCore::Types::Primitive::InvariantControl::Single::Result>]
21
+ # @return [void]
22
+ #
23
+ # @api private
24
+ # @since 0.2.0
25
+ def initialize(invariant_chain, checked_value, invariant_results)
26
+ @invariant_chain = invariant_chain
27
+ @checked_value = checked_value
28
+ @invariant_results = invariant_results
29
+ end
30
+
31
+ # @return [Boolean]
32
+ #
33
+ # @api private
34
+ # @since 0.2.0
35
+ def success?
36
+ invariant_results.all?(&:success?)
37
+ end
38
+
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ # @since 0.2.0
43
+ def failure?
44
+ invariant_results.any?(&:failure?)
45
+ end
46
+
47
+ # @return [Array<String>]
48
+ #
49
+ # @api private
50
+ # @since 0.1.0
51
+ def error_codes
52
+ invariant_results.select(&:failure?).map do |invariant_result|
53
+ "#{invariant_chain.name}.#{invariant_result.invariant.name}".tap(&:freeze)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Single::Result>]
60
+ #
61
+ # @api private
62
+ # @since 0.2.0
63
+ attr_reader :invariant_results
64
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ # @version 0.3.0
6
+ class SmartCore::Types::Primitive::InvariantControl::Chain
7
+ require_relative 'chain/result'
8
+
9
+ # @return [String]
10
+ #
11
+ # @api private
12
+ # @since 0.2.0
13
+ attr_reader :name
14
+
15
+ # @param name [String]
16
+ # @return [void]
17
+ #
18
+ # @api private
19
+ # @since 0.1.0
20
+ def initialize(name)
21
+ @name = name.dup.tap(&:freeze)
22
+ @invariants = []
23
+ end
24
+
25
+ # @param invariant [SmartCore::Types::Primitive::InvariantControl::Single]
26
+ # @return [void]
27
+ #
28
+ # @api private
29
+ # @since 0.2.0
30
+ def add_invariant(invariant)
31
+ invariants << invariant
32
+ end
33
+
34
+ # @param value [Any]
35
+ # @param runtime_attributes [Array<Any>]
36
+ # @return [SmartCore::Types::Primitive::InvariantControl::Chain::Result]
37
+ #
38
+ # @api private
39
+ # @since 0.2.0
40
+ # @version 0.3.0
41
+ def check(value, runtime_attributes)
42
+ invariant_results = [].tap do |results|
43
+ invariants.each do |invariant|
44
+ result = invariant.check(value, runtime_attributes).tap { |res| results << res }
45
+ break if result.failure?
46
+ end
47
+ end
48
+
49
+ SmartCore::Types::Primitive::InvariantControl::Chain::Result.new(
50
+ self, value, invariant_results
51
+ )
52
+ end
53
+
54
+ private
55
+
56
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Single>]
57
+ #
58
+ # @api private
59
+ # @since 0.2.0
60
+ attr_reader :invariants
61
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Factory::ChainDefinitionContext
6
+ # @return [SmartCore::Types::Primitive::InvariantControl::Chain]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :___chain___
11
+
12
+ # @param chain_name [String]
13
+ # @return [void]
14
+ #
15
+ # @api privae
16
+ # @since 0.2.0
17
+ def initialize(chain_name)
18
+ @___chain___ = SmartCore::Types::Primitive::InvariantControl::Chain.new(chain_name)
19
+ end
20
+
21
+ # @param invariant_name [String, Symbol]
22
+ # @param invariant_definition [Block]
23
+ # @return [void]
24
+ #
25
+ # @api private
26
+ # @since 0.2.0
27
+ def invariant(invariant_name, &invariant_definition)
28
+ SmartCore::Types::Primitive::Factory::DefinitionContext.vaildate_invariant_attributes!(
29
+ invariant_name,
30
+ &invariant_definition
31
+ )
32
+
33
+ ___chain___.add_invariant(
34
+ SmartCore::Types::Primitive::InvariantControl::Single.create(
35
+ invariant_name, invariant_definition
36
+ )
37
+ )
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ module SmartCore::Types::Primitive::InvariantControl::Factory
6
+ require_relative 'factory/chain_definition_context'
7
+
8
+ class << self
9
+ # @param invariant_chains [Hash<String,Array<Proc>]
10
+ # @param invariants [Hash<String,Proc>]
11
+ # @return [SmartCore::Types::Primitive::InvariantControl]
12
+ #
13
+ # @api private
14
+ # @since 0.2.0
15
+ def create(invariant_chains, invariants)
16
+ completed_invariant_chains = build_invariant_chains(invariant_chains)
17
+ completed_invariants = build_invariants(invariants)
18
+
19
+ SmartCore::Types::Primitive::InvariantControl.new(
20
+ completed_invariant_chains,
21
+ completed_invariants
22
+ )
23
+ end
24
+
25
+ private
26
+
27
+ # @param invariant_chains [Hash<String,Array<Proc>]
28
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Chain>]
29
+ #
30
+ # @api private
31
+ # @since 0.2.0
32
+ def build_invariant_chains(invariant_chains)
33
+ invariant_chains.map do |chain_name, chain_invariants|
34
+ context = ChainDefinitionContext.new(chain_name)
35
+ chain_invariants.each { |invariant_logic| context.instance_eval(&invariant_logic) }
36
+ context.___chain___
37
+ end
38
+ end
39
+
40
+ # @param invariants [Hash<String,Proc>]
41
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Single>]
42
+ #
43
+ # @api private
44
+ # @since 0.2.0
45
+ def build_invariants(invariants)
46
+ invariants.map do |invariant_name, invariant_logics|
47
+ SmartCore::Types::Primitive::InvariantControl::Single.create(
48
+ invariant_name,
49
+ invariant_logics
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Result
6
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Chain::Result>]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :chain_results
11
+
12
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Single::Result>]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ attr_reader :single_results
17
+
18
+ # @param invariant_control [SmartCore::Types::Primitive::InvariantControl]
19
+ # @param checked_value [Any]
20
+ # @return [void]
21
+ #
22
+ # @api private
23
+ # @since 0.2.0
24
+ def initialize(invariant_control, checked_value)
25
+ @invariant_control = invariant_control
26
+ @checked_value = checked_value
27
+ @chain_results = []
28
+ @single_results = []
29
+ end
30
+
31
+ # @return [Array<String>]
32
+ #
33
+ # @api private
34
+ # @since 0.2.0
35
+ def invariant_errors
36
+ collect_invariant_errors
37
+ end
38
+
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ # @since 0.2.0
43
+ def success?
44
+ chain_results.all(&:success?) && single_results.all?(&:success?)
45
+ end
46
+
47
+ # @return [Boolean]
48
+ #
49
+ # @api private
50
+ # @since 0.2.0
51
+ def failure?
52
+ !success?
53
+ end
54
+
55
+ # @param result [SmartCore::Types::Primitive::InvariantControl::Chain::Result]
56
+ # @return [void]
57
+ #
58
+ # @api private
59
+ # @since 0.2.0
60
+ def add_chain_result(result)
61
+ chain_results << result
62
+ end
63
+
64
+ # @param result [SmartCore::Types::Primitive::InvariantControl::Single::Result]
65
+ # @return [void]
66
+ #
67
+ # @api private
68
+ # @since 0.2.0
69
+ def add_single_result(result)
70
+ single_results << result
71
+ end
72
+
73
+ private
74
+
75
+ # @return [SmartCore::Types::Primitive::InvariantControl]
76
+ #
77
+ # @api private
78
+ # @since 0.2.0
79
+ attr_reader :invariant_control
80
+
81
+ # @return [Any]
82
+ #
83
+ # @api private
84
+ # @since 0.2.0
85
+ attr_reader :checked_value
86
+
87
+ # @return [Array<String>]
88
+ #
89
+ # @api private
90
+ # @since 0.2.0
91
+ def collect_invariant_errors
92
+ [].tap do |invariant_errors|
93
+ # collect invariant errors from invariant chains
94
+ chain_results.select(&:failure?).each do |chain_result|
95
+ invariant_errors.concat(chain_result.error_codes)
96
+ end
97
+
98
+ # collect invariant errors from single invariants
99
+ single_results.select(&:failure?).each do |single_result|
100
+ invariant_errors.concat(single_result.error_codes)
101
+ end
102
+ end.tap(&:freeze)
103
+ end
104
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Single::Result
6
+ # @return [SmartCore::Types::Primitive::InvariantControl::Single]
7
+ #
8
+ # @api private
9
+ # @since 0.2.0
10
+ attr_reader :invariant
11
+
12
+ # @return [Any]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ attr_reader :checked_value
17
+
18
+ # @param invariant [SmartCore::Types::Primitive::InvariantControl::Single]
19
+ # @param checked_value [Any]
20
+ # @param is_valid_check [Boolean]
21
+ # @return [void]
22
+ #
23
+ # @api private
24
+ # @since 0.2.0
25
+ def initialize(invariant, checked_value, is_valid_check)
26
+ @invariant = invariant
27
+ @checked_value = checked_value
28
+ @is_valid_check = is_valid_check
29
+ end
30
+
31
+ # @return [Boolean]
32
+ #
33
+ # @api private
34
+ # @since 0.2.0
35
+ def success?
36
+ is_valid_check
37
+ end
38
+
39
+ # @return [Boolean]
40
+ #
41
+ # @api private
42
+ # @since 0.2.0
43
+ def failure?
44
+ !success?
45
+ end
46
+
47
+ # @return [Array<String>]
48
+ #
49
+ # @api private
50
+ # @since 0.2.0
51
+ def error_codes
52
+ success? ? [] : [invariant.name]
53
+ end
54
+
55
+ private
56
+
57
+ # @return [Boolean]
58
+ #
59
+ # @api private
60
+ # @since 0.2.0
61
+ attr_reader :is_valid_check
62
+ alias_method :valid_check?, :is_valid_check
63
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ # @version 0.3.0
6
+ class SmartCore::Types::Primitive::InvariantControl::Single
7
+ require_relative 'single/result'
8
+
9
+ class << self
10
+ # @param name [String, Symbol]
11
+ # @param invariant_checker [Proc]
12
+ # @return [SmartCore::Types::Primitive::InvariantControl::Single]
13
+ #
14
+ # @api private
15
+ # @since 0.2.0
16
+ def create(name, invariant_checker)
17
+ new(name.to_s, invariant_checker)
18
+ end
19
+ end
20
+
21
+ # @return [String]
22
+ #
23
+ # @api private
24
+ # @since 0.2.0
25
+ attr_reader :name
26
+
27
+ # @param name [String]
28
+ # @param invariant_checker [Proc]
29
+ # @return [void]
30
+ #
31
+ # @api private
32
+ # @since 0.2.0
33
+ def initialize(name, invariant_checker)
34
+ @name = name.dup.tap(&:freeze)
35
+ @invariant_checker = invariant_checker
36
+ end
37
+
38
+ # @param value [Any]
39
+ # @param runtime_attributes [Array<Any>]
40
+ # @return [SmartCore::Types::Primitive::InvariantControl::Single::Result]
41
+ #
42
+ # @api private
43
+ # @since 0.2.0
44
+ # @version 0.3.0
45
+ def check(value, runtime_attributes)
46
+ validation_result = !!invariant_checker.call(value, runtime_attributes)
47
+ Result.new(self, value, validation_result)
48
+ end
49
+
50
+ private
51
+
52
+ # @return [Proc]
53
+ #
54
+ # @api private
55
+ # @since 0.2.0
56
+ attr_reader :invariant_checker
57
+ end