smart_types 0.1.0.alpha3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/.travis.yml +6 -5
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile.lock +74 -48
  6. data/README.md +292 -22
  7. data/Rakefile +1 -1
  8. data/bin/console +2 -2
  9. data/lib/smart_core/types/errors.rb +4 -0
  10. data/lib/smart_core/types/primitive.rb +67 -20
  11. data/lib/smart_core/types/primitive/factory.rb +48 -8
  12. data/lib/smart_core/types/primitive/factory/definition_context.rb +116 -6
  13. data/lib/smart_core/types/primitive/invariant_control.rb +64 -0
  14. data/lib/smart_core/types/primitive/invariant_control/chain.rb +58 -0
  15. data/lib/smart_core/types/primitive/invariant_control/chain/result.rb +64 -0
  16. data/lib/smart_core/types/primitive/invariant_control/factory.rb +54 -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/result.rb +104 -0
  19. data/lib/smart_core/types/primitive/invariant_control/single.rb +54 -0
  20. data/lib/smart_core/types/primitive/invariant_control/single/result.rb +63 -0
  21. data/lib/smart_core/types/primitive/mult_factory.rb +25 -10
  22. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +5 -3
  23. data/lib/smart_core/types/primitive/mult_validator.rb +34 -0
  24. data/lib/smart_core/types/primitive/mult_validator/result.rb +8 -0
  25. data/lib/smart_core/types/primitive/nilable_factory.rb +24 -9
  26. data/lib/smart_core/types/primitive/nilable_validator.rb +83 -0
  27. data/lib/smart_core/types/primitive/nilable_validator/result.rb +78 -0
  28. data/lib/smart_core/types/primitive/sum_factory.rb +25 -10
  29. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +4 -2
  30. data/lib/smart_core/types/primitive/sum_validator.rb +101 -0
  31. data/lib/smart_core/types/primitive/sum_validator/result.rb +100 -0
  32. data/lib/smart_core/types/primitive/undefined_caster.rb +3 -4
  33. data/lib/smart_core/types/primitive/validator.rb +84 -0
  34. data/lib/smart_core/types/primitive/validator/result.rb +78 -0
  35. data/lib/smart_core/types/system.rb +21 -5
  36. data/lib/smart_core/types/value.rb +17 -0
  37. data/lib/smart_core/types/value/big_decimal.rb +28 -0
  38. data/lib/smart_core/types/value/comparable.rb +13 -0
  39. data/lib/smart_core/types/value/date.rb +21 -0
  40. data/lib/smart_core/types/value/date_time.rb +21 -0
  41. data/lib/smart_core/types/value/enumerable.rb +13 -0
  42. data/lib/smart_core/types/value/enumerator.rb +13 -0
  43. data/lib/smart_core/types/value/enumerator_chain.rb +13 -0
  44. data/lib/smart_core/types/value/float.rb +6 -2
  45. data/lib/smart_core/types/value/hash.rb +8 -1
  46. data/lib/smart_core/types/value/integer.rb +10 -3
  47. data/lib/smart_core/types/value/io.rb +13 -0
  48. data/lib/smart_core/types/value/method.rb +9 -0
  49. data/lib/smart_core/types/value/nil.rb +9 -0
  50. data/lib/smart_core/types/value/numeric.rb +13 -3
  51. data/lib/smart_core/types/value/proc.rb +11 -1
  52. data/lib/smart_core/types/value/range.rb +9 -0
  53. data/lib/smart_core/types/value/rational.rb +13 -0
  54. data/lib/smart_core/types/value/set.rb +13 -0
  55. data/lib/smart_core/types/value/string.rb +7 -1
  56. data/lib/smart_core/types/value/string_io.rb +13 -0
  57. data/lib/smart_core/types/value/symbol.rb +7 -1
  58. data/lib/smart_core/types/value/text.rb +16 -1
  59. data/lib/smart_core/types/value/time.rb +21 -0
  60. data/lib/smart_core/types/value/time_based.rb +29 -0
  61. data/lib/smart_core/types/value/unbound_method.rb +9 -0
  62. data/lib/smart_core/types/version.rb +2 -2
  63. data/smart_types.gemspec +6 -5
  64. metadata +64 -22
  65. data/lib/smart_core/types/primitive/mult_checker.rb +0 -31
  66. data/lib/smart_core/types/primitive/nilable_checker.rb +0 -37
  67. data/lib/smart_core/types/primitive/sum_checker.rb +0 -31
  68. data/lib/smart_core/types/system/definition_dsl.rb +0 -40
  69. data/lib/smart_core/types/system/producer_dsl.rb +0 -30
@@ -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
@@ -15,14 +15,13 @@ class SmartCore::Types::Primitive::UndefinedCaster < SmartCore::Types::Primitive
15
15
  # @param value [Any]
16
16
  # @return [void]
17
17
  #
18
- # @raise [SmartCore::Types::TypeCastingError]
18
+ # @raise [SmartCore::Types::TypeCastingUnsupportedError]
19
19
  #
20
20
  # @pai private
21
21
  # @since 0.1.0
22
22
  def call(value)
23
- raise(
24
- SmartCore::Types::TypeCastingError,
23
+ raise(SmartCore::Types::TypeCastingUnsupportedError, <<~ERROR_MESSAGE)
25
24
  'This type has no support for type casting'
26
- )
25
+ ERROR_MESSAGE
27
26
  end
28
27
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api private
4
+ # @since 0.2.0
5
+ class SmartCore::Types::Primitive::Validator
6
+ require_relative 'validator/result'
7
+
8
+ # @return [SmartCore::Type::Primitive]
9
+ #
10
+ # @api private
11
+ # @since 0.2.0
12
+ attr_reader :type
13
+
14
+ # @return [SmartCore::Types::Primitive::Checker]
15
+ #
16
+ # @api private
17
+ # @since 0.2.0
18
+ attr_reader :type_checker
19
+
20
+ # @return [SmartCore::Types::Primitive::InvariantControl]
21
+ #
22
+ # @api private
23
+ # @since 0.2.0
24
+ attr_reader :invariant_control
25
+
26
+ # @param type_checker [
27
+ # SmartCore::Types::Primitive::Checker,
28
+ # SmartCore::Types::Primitive::MultChecker,
29
+ # SmartCore::Types::Primitive::SumChecker
30
+ # ]
31
+ # @param invariant_control [SmartCore::Types::Primitive::InvariantControl]
32
+ # @return [void]
33
+ #
34
+ # @api private
35
+ # @since 0.2.0
36
+ def initialize(type_checker, invariant_control)
37
+ @type = nil
38
+ @type_checker = type_checker
39
+ @invariant_control = invariant_control
40
+ end
41
+
42
+ # @param type [SmartCore::Types::Primitive]
43
+ # @return [void]
44
+ #
45
+ # @api private
46
+ # @since 0.2.0
47
+ def ___assign_type___(type)
48
+ @type = type
49
+ end
50
+
51
+ # @param value [Any]
52
+ # @return [Boolean]
53
+ #
54
+ # @api private
55
+ # @since 0.2.0
56
+ def valid?(value)
57
+ validate(value).success?
58
+ end
59
+
60
+ # @param value [Any]
61
+ # @return [SmartCore::Types::Primitive::Validator::Result]
62
+ #
63
+ # @api private
64
+ # @since 0.2.0
65
+ def validate(value)
66
+ checker_result = type_checker.call(value) # => Boolean
67
+ return Result.new(type, value, checker_result) unless checker_result
68
+ invariant_result = invariant_control.check(value)
69
+ invariant_errors = invariant_result.invariant_errors.map { |error| "#{type.name}.#{error}" }
70
+ Result.new(type, value, checker_result, invariant_errors)
71
+ end
72
+
73
+ # @param value [Any]
74
+ # @return [void]
75
+ #
76
+ # @raise [SmartCore::Types::TypeError]
77
+ #
78
+ # @api private
79
+ # @since 0.2.0
80
+ def validate!(value)
81
+ return if validate(value).success?
82
+ raise(SmartCore::Types::TypeError, 'Invalid type')
83
+ end
84
+ 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
@@ -1,11 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @api private
3
+ # @api public
4
4
  # @since 0.1.0
5
5
  module SmartCore::Types::System
6
- require_relative 'system/producer_dsl'
7
- require_relative 'system/definition_dsl'
6
+ class << self
7
+ # @param types [Array<SmartCore::Types::Pirmitive>]
8
+ # @param type_definition [Block]
9
+ # @return [SmartCore::Types::Primitive]
10
+ #
11
+ # @api public
12
+ # @since 0.1.0
13
+ def type_sum(*types, &type_definition)
14
+ SmartCore::Types::Primitive::SumFactory.create_type(types, type_definition)
15
+ end
8
16
 
9
- # @since 0.1.0
10
- include SmartCore::Types::System::DefinitionDSL
17
+ # @param types [Array<SmartCore::Types::Pirmitive>]
18
+ # @param type_definition [Block]
19
+ # @return [SmartCore::Types::Primitive]
20
+ #
21
+ # @api public
22
+ # @since 0.1.0
23
+ def type_mult(*types, &type_definition)
24
+ SmartCore::Types::Primitive::MultFactory.create_type(types, type_definition)
25
+ end
26
+ end
11
27
  end
@@ -3,7 +3,9 @@
3
3
  # @api public
4
4
  # @since 0.1.0
5
5
  class SmartCore::Types::Value < SmartCore::Types::Primitive
6
+ require_relative 'value/nil'
6
7
  require_relative 'value/string'
8
+ require_relative 'value/string_io'
7
9
  require_relative 'value/symbol'
8
10
  require_relative 'value/text'
9
11
  require_relative 'value/integer'
@@ -12,8 +14,23 @@ class SmartCore::Types::Value < SmartCore::Types::Primitive
12
14
  require_relative 'value/boolean'
13
15
  require_relative 'value/array'
14
16
  require_relative 'value/hash'
17
+ require_relative 'value/io'
15
18
  require_relative 'value/proc'
16
19
  require_relative 'value/class'
17
20
  require_relative 'value/module'
18
21
  require_relative 'value/any'
22
+ require_relative 'value/time'
23
+ require_relative 'value/date'
24
+ require_relative 'value/date_time'
25
+ require_relative 'value/time_based'
26
+ require_relative 'value/enumerable'
27
+ require_relative 'value/enumerator'
28
+ require_relative 'value/enumerator_chain'
29
+ require_relative 'value/comparable'
30
+ require_relative 'value/big_decimal'
31
+ require_relative 'value/range'
32
+ require_relative 'value/method'
33
+ require_relative 'value/unbound_method'
34
+ require_relative 'value/set'
35
+ require_relative 'value/rational'
19
36
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+ require 'bigdecimal/util'
5
+
6
+ # @api public
7
+ # @since 0.1.0
8
+ SmartCore::Types::Value.define_type(:BigDecimal) do |type|
9
+ type.define_checker do |value|
10
+ value.is_a?(::BigDecimal)
11
+ end
12
+
13
+ type.define_caster do |value|
14
+ if SmartCore::Types::Value::Float.valid?(value)
15
+ value = SmartCore::Types::Value::String.cast(value)
16
+ end
17
+
18
+ begin
19
+ ::Kernel.BigDecimal(value)
20
+ rescue ::ArgumentError, ::TypeError
21
+ begin
22
+ ::Kernel.BigDecimal(value.to_d)
23
+ rescue ::ArgumentError, ::TypeError, ::NoMethodError
24
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to BigDecimal')
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ SmartCore::Types::Value.define_type(:Comparable) do |type|
6
+ type.define_checker do |value|
7
+ # TODO: realize
8
+ end
9
+
10
+ type.define_caster do |value|
11
+ # TODO: realize
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ # @api public
6
+ # @since 0.1.0
7
+ SmartCore::Types::Value.define_type(:Date) do |type|
8
+ type.define_checker do |value|
9
+ value.is_a?(::Date) || value == ::Date::Infinity
10
+ end
11
+
12
+ type.define_caster do |value|
13
+ next value if value.is_a?(::Date) || value == ::Date::Infinity
14
+
15
+ begin
16
+ ::Date.parse(value)
17
+ rescue ::Date::Error, ::TypeError
18
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Date')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ # @api public
6
+ # @since 0.1.0
7
+ SmartCore::Types::Value.define_type(:DateTime) do |type|
8
+ type.define_checker do |value|
9
+ value.is_a?(::DateTime) || value == ::DateTime::Infinity
10
+ end
11
+
12
+ type.define_caster do |value|
13
+ next value if value.is_a?(::DateTime) || value == ::DateTime::Infinity
14
+
15
+ begin
16
+ ::DateTime.parse(value)
17
+ rescue ::Date::Error, ::TypeError
18
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to DateTime')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ SmartCore::Types::Value.define_type(:Enumerable) do |type|
6
+ type.define_checker do |value|
7
+ # TODO: realize
8
+ end
9
+
10
+ type.define_caster do |value|
11
+ # TODO: realize
12
+ end
13
+ end