smart_types 0.1.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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