smart_types 0.1.0 → 0.2.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -1
  3. data/CHANGELOG.md +17 -0
  4. data/Gemfile.lock +59 -48
  5. data/README.md +178 -31
  6. data/Rakefile +0 -1
  7. data/bin/console +2 -2
  8. data/lib/smart_core/types/primitive.rb +54 -15
  9. data/lib/smart_core/types/primitive/factory.rb +46 -7
  10. data/lib/smart_core/types/primitive/factory/definition_context.rb +114 -4
  11. data/lib/smart_core/types/primitive/invariant_control.rb +64 -0
  12. data/lib/smart_core/types/primitive/invariant_control/chain.rb +58 -0
  13. data/lib/smart_core/types/primitive/invariant_control/chain/result.rb +64 -0
  14. data/lib/smart_core/types/primitive/invariant_control/factory.rb +54 -0
  15. data/lib/smart_core/types/primitive/invariant_control/factory/chain_definition_context.rb +39 -0
  16. data/lib/smart_core/types/primitive/invariant_control/result.rb +104 -0
  17. data/lib/smart_core/types/primitive/invariant_control/single.rb +54 -0
  18. data/lib/smart_core/types/primitive/invariant_control/single/result.rb +63 -0
  19. data/lib/smart_core/types/primitive/mult_factory.rb +25 -10
  20. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +4 -2
  21. data/lib/smart_core/types/primitive/mult_validator.rb +34 -0
  22. data/lib/smart_core/types/primitive/mult_validator/result.rb +8 -0
  23. data/lib/smart_core/types/primitive/nilable_factory.rb +24 -9
  24. data/lib/smart_core/types/primitive/nilable_validator.rb +83 -0
  25. data/lib/smart_core/types/primitive/nilable_validator/result.rb +78 -0
  26. data/lib/smart_core/types/primitive/sum_factory.rb +25 -10
  27. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +3 -1
  28. data/lib/smart_core/types/primitive/sum_validator.rb +101 -0
  29. data/lib/smart_core/types/primitive/sum_validator/result.rb +100 -0
  30. data/lib/smart_core/types/primitive/validator.rb +84 -0
  31. data/lib/smart_core/types/primitive/validator/result.rb +78 -0
  32. data/lib/smart_core/types/value.rb +9 -0
  33. data/lib/smart_core/types/value/enumerator.rb +13 -0
  34. data/lib/smart_core/types/value/enumerator_chain.rb +13 -0
  35. data/lib/smart_core/types/value/io.rb +13 -0
  36. data/lib/smart_core/types/value/method.rb +9 -0
  37. data/lib/smart_core/types/value/nil.rb +0 -2
  38. data/lib/smart_core/types/value/range.rb +9 -0
  39. data/lib/smart_core/types/value/rational.rb +13 -0
  40. data/lib/smart_core/types/value/set.rb +13 -0
  41. data/lib/smart_core/types/value/string_io.rb +13 -0
  42. data/lib/smart_core/types/value/unbound_method.rb +9 -0
  43. data/lib/smart_core/types/version.rb +2 -1
  44. data/smart_types.gemspec +5 -4
  45. metadata +53 -17
  46. data/lib/smart_core/types/primitive/mult_checker.rb +0 -31
  47. data/lib/smart_core/types/primitive/nilable_checker.rb +0 -37
  48. data/lib/smart_core/types/primitive/sum_checker.rb +0 -31
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Chain
6
+ require_relative 'chain/result'
7
+
8
+ # @return [String]
9
+ #
10
+ # @api private
11
+ # @since 0.2.0
12
+ attr_reader :name
13
+
14
+ # @param name [String]
15
+ # @return [void]
16
+ #
17
+ # @api private
18
+ # @since 0.1.0
19
+ def initialize(name)
20
+ @name = name.dup.tap(&:freeze)
21
+ @invariants = []
22
+ end
23
+
24
+ # @param invariant [SmartCore::Types::Primitive::InvariantControl::Single]
25
+ # @return [void]
26
+ #
27
+ # @api private
28
+ # @since 0.2.0
29
+ def add_invariant(invariant)
30
+ invariants << invariant
31
+ end
32
+
33
+ # @param value [Any]
34
+ # @return [SmartCore::Types::Primitive::InvariantControl::Chain::Result]
35
+ #
36
+ # @api private
37
+ # @since 0.2.0
38
+ def check(value)
39
+ invariant_results = [].tap do |results|
40
+ invariants.each do |invariant|
41
+ result = invariant.check(value).tap { |res| results << res }
42
+ break if result.failure?
43
+ end
44
+ end
45
+
46
+ SmartCore::Types::Primitive::InvariantControl::Chain::Result.new(
47
+ self, value, invariant_results
48
+ )
49
+ end
50
+
51
+ private
52
+
53
+ # @return [Array<SmartCore::Types::Primitive::InvariantControl::Single>]
54
+ #
55
+ # @api private
56
+ # @since 0.2.0
57
+ attr_reader :invariants
58
+ end
@@ -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,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,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,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,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::InvariantControl::Single
6
+ require_relative 'single/result'
7
+
8
+ class << self
9
+ # @param name [String, Symbol]
10
+ # @param invariant_checker [Proc]
11
+ # @return [SmartCore::Types::Primitive::InvariantControl::Single]
12
+ #
13
+ # @api private
14
+ # @since 0.2.0
15
+ def create(name, invariant_checker)
16
+ new(name.to_s, invariant_checker)
17
+ end
18
+ end
19
+
20
+ # @return [String]
21
+ #
22
+ # @api private
23
+ # @since 0.2.0
24
+ attr_reader :name
25
+
26
+ # @param name [String]
27
+ # @param invariant_checker [Proc]
28
+ # @return [void]
29
+ #
30
+ # @api private
31
+ # @since 0.2.0
32
+ def initialize(name, invariant_checker)
33
+ @name = name.dup.tap(&:freeze)
34
+ @invariant_checker = invariant_checker
35
+ end
36
+
37
+ # @param value [Any]
38
+ # @return [SmartCore::Types::Primitive::InvariantControl::Single::Result]
39
+ #
40
+ # @api private
41
+ # @since 0.2.0
42
+ def check(value)
43
+ validation_result = !!invariant_checker.call(value)
44
+ Result.new(self, value, validation_result)
45
+ end
46
+
47
+ private
48
+
49
+ # @return [Proc]
50
+ #
51
+ # @api private
52
+ # @since 0.2.0
53
+ attr_reader :invariant_checker
54
+ 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
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # @version 0.2.0
5
6
  module SmartCore::Types::Primitive::MultFactory
6
7
  require_relative 'mult_factory/definition_context'
7
8
 
@@ -12,11 +13,14 @@ module SmartCore::Types::Primitive::MultFactory
12
13
  #
13
14
  # @api private
14
15
  # @since 0.1.0
16
+ # @version 0.2.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_validator = build_type_validator(types, type_definitions)
18
20
  type_caster = build_type_caster(types, type_definitions)
19
- build_type(type_checker, type_caster)
21
+ build_type(type_validator, type_caster).tap do |type|
22
+ assign_type_validator(type, type_validator)
23
+ end
20
24
  end
21
25
 
22
26
  private
@@ -34,12 +38,12 @@ module SmartCore::Types::Primitive::MultFactory
34
38
 
35
39
  # @param types [Array<SmartCore::Types::Primtive>]
36
40
  # @param type_definitions [SmartCore::Types::Primitive::MultFactory::DefinitionContext]
37
- # @return [SmartCore::Types::Primitive::MultChecker]
41
+ # @return [SmartCore::Types::Primitive::MultValidator]
38
42
  #
39
43
  # @api private
40
- # @since 0.1.0
41
- def build_type_checker(types, type_definitions)
42
- SmartCore::Types::Primitive::MultChecker.new(*types.map(&:checker))
44
+ # @since 0.2.0
45
+ def build_type_validator(types, type_definitions)
46
+ SmartCore::Types::Primitive::MultValidator.new(*types.map(&:validator))
43
47
  end
44
48
 
45
49
  # @param types [Array<SmartCore::Types::Primtive>]
@@ -49,21 +53,32 @@ module SmartCore::Types::Primitive::MultFactory
49
53
  # @api private
50
54
  # @since 0.1.0
51
55
  def build_type_caster(types, type_definitions)
52
- if type_definitions.type_caster.nil?
56
+ if type_definitions.type_caster == nil
53
57
  SmartCore::Types::Primitive::UndefinedCaster.new
54
58
  else
55
59
  SmartCore::Types::Primitive::Caster.new(type_definitions.type_caster)
56
60
  end
57
61
  end
58
62
 
59
- # @param type_checker [SmartCore::Types::Primitive::MultChecker]
63
+ # @param type [SmartCore::Types::Primitive]
64
+ # @param type_validator [SmartCore::Types::Primitive::MultValidator]
65
+ # @return [void]
66
+ #
67
+ # @api private
68
+ # @since 0.2.0
69
+ def assign_type_validator(type, type_validator)
70
+ type_validator.___assign_type___(type)
71
+ end
72
+
73
+ # @param type_validator [SmartCore::Types::Primitive::MultValidator]
60
74
  # @param type_caster [SmartCore::Types::Primitive::Caster]
61
75
  # @return [SmartCore::Types::Primitive]
62
76
  #
63
77
  # @api private
64
78
  # @since 0.1.0
65
- def build_type(type_checker, type_caster)
66
- SmartCore::Types::Primitive.new(type_checker, type_caster)
79
+ # @version 0.2.0
80
+ def build_type(type_validator, type_caster)
81
+ SmartCore::Types::Primitive.new(nil, type_validator, type_caster)
67
82
  end
68
83
  end
69
84
  end