smart_types 0.1.0.alpha5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -5,6 +5,7 @@
5
5
  class SmartCore::Types::Value < SmartCore::Types::Primitive
6
6
  require_relative 'value/nil'
7
7
  require_relative 'value/string'
8
+ require_relative 'value/string_io'
8
9
  require_relative 'value/symbol'
9
10
  require_relative 'value/text'
10
11
  require_relative 'value/integer'
@@ -13,8 +14,23 @@ class SmartCore::Types::Value < SmartCore::Types::Primitive
13
14
  require_relative 'value/boolean'
14
15
  require_relative 'value/array'
15
16
  require_relative 'value/hash'
17
+ require_relative 'value/io'
16
18
  require_relative 'value/proc'
17
19
  require_relative 'value/class'
18
20
  require_relative 'value/module'
19
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'
20
36
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Array) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Array)
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+ require 'bigdecimal/util'
5
+
6
+ using SmartCore::Ext::BasicObjectAsObject
7
+
8
+ # @api public
9
+ # @since 0.1.0
10
+ # @version 0.3.0
11
+ SmartCore::Types::Value.define_type(:BigDecimal) do |type|
12
+ type.define_checker do |value|
13
+ value.is_a?(::BigDecimal)
14
+ end
15
+
16
+ type.define_caster do |value|
17
+ if SmartCore::Types::Value::Numeric.valid?(value)
18
+ value = SmartCore::Types::Value::String.cast(value)
19
+ end
20
+
21
+ begin
22
+ ::Kernel.BigDecimal(value)
23
+ rescue ::ArgumentError, ::TypeError
24
+ begin
25
+ ::Kernel.BigDecimal(value.to_d)
26
+ rescue ::ArgumentError, ::TypeError, ::NoMethodError
27
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to BigDecimal')
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Boolean) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::TrueClass) || value.is_a?(::FalseClass)
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Class) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Class)
@@ -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,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
7
+ # @api public
8
+ # @since 0.1.0
9
+ # @version 0.3.0
10
+ SmartCore::Types::Value.define_type(:Date) do |type|
11
+ type.define_checker do |value|
12
+ value.is_a?(::Date) || value == ::Date::Infinity
13
+ end
14
+
15
+ type.define_caster do |value|
16
+ next value if value.is_a?(::Date) || value == ::Date::Infinity
17
+
18
+ begin
19
+ ::Date.parse(value)
20
+ rescue ::Date::Error, ::TypeError
21
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Date')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
7
+ # @api public
8
+ # @since 0.1.0
9
+ # @version 0.3.0
10
+ SmartCore::Types::Value.define_type(:DateTime) do |type|
11
+ type.define_checker do |value|
12
+ value.is_a?(::DateTime) || value == ::DateTime::Infinity
13
+ end
14
+
15
+ type.define_caster do |value|
16
+ next value if value.is_a?(::DateTime) || value == ::DateTime::Infinity
17
+
18
+ begin
19
+ ::DateTime.parse(value)
20
+ rescue ::Date::Error, ::TypeError
21
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to DateTime')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.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
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.0
5
+ SmartCore::Types::Value.define_type(:Enumerator) 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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.0
5
+ SmartCore::Types::Value.define_type(:EnumeratorChain) 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
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Float) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Float)
@@ -9,9 +12,13 @@ SmartCore::Types::Value.define_type(:Float) do |type|
9
12
 
10
13
  type.define_caster do |value|
11
14
  begin
12
- Float(value)
15
+ ::Kernel.Float(value)
13
16
  rescue ::TypeError, ::ArgumentError
14
- value.to_f
17
+ begin
18
+ ::Kernel.Float(value.to_f)
19
+ rescue ::NoMethodError, ::TypeError, ::ArgumentError
20
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Float')
21
+ end
15
22
  end
16
23
  end
17
24
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Hash) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Hash)
@@ -11,7 +14,14 @@ SmartCore::Types::Value.define_type(:Hash) do |type|
11
14
  begin
12
15
  ::Kernel.Hash(value)
13
16
  rescue ::TypeError
14
- {}
17
+ begin
18
+ # NOTE:
19
+ # - ::Kernel.Hash does not invoke `#to_h` under the hood (it invokes `#to_hash`)
20
+ # - ::Kernel.Hash is used to validate the returned value from `#to_h`
21
+ ::Kernel.Hash(value.to_h)
22
+ rescue ::TypeError, ::NoMethodError, ::ArgumentError
23
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Hash')
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Integer) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Integer)
@@ -9,9 +12,16 @@ SmartCore::Types::Value.define_type(:Integer) do |type|
9
12
 
10
13
  type.define_caster do |value|
11
14
  begin
12
- Integer(value)
13
- rescue ::TypeError, ::ArgumentError
14
- value.to_i
15
+ ::Kernel.Integer(value)
16
+ rescue ::TypeError, ::ArgumentError, ::FloatDomainError
17
+ begin
18
+ # NOTE: for cases like this:
19
+ # => ::Kernel.Integer(nil) # => ::TypeError
20
+ # => ::Kernel.Integer(nil.to_i) # => 0 (::Kernel.Integer used as validation layer)
21
+ ::Kernel.Integer(value.to_i)
22
+ rescue ::TypeError, ::NoMethodError, ::ArgumentError, ::FloatDomainError
23
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Integer')
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.0
5
+ SmartCore::Types::Value.define_type(:IO) 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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.0
5
+ SmartCore::Types::Value.define_type(:Method) do |type|
6
+ type.define_checker do |value|
7
+ # TODO: realize
8
+ end
9
+ end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Module) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Module)
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @api public
4
+ # @since 0.1.0
3
5
  SmartCore::Types::Value.define_type(:Nil) do |type|
4
6
  type.define_checker do |value|
5
- # rubocop:disable Style/NilComparison
6
- value == nil # NOTE: #nil? is not used cuz BasicObject has no #nil? method
7
- # rubocop:enable Style/NilComparison
7
+ value == nil # NOTE: #nil? is not used cuz BasicObject hasn't #nil? method
8
8
  end
9
9
  end
@@ -1,17 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Numeric) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Numeric)
8
11
  end
9
12
 
10
13
  type.define_caster do |value|
14
+ next value if value.is_a?(::Numeric)
15
+
11
16
  begin
12
- Float(value)
13
- rescue ::TypeError, ::ArgumentError
14
- value.to_f
17
+ SmartCore::Types::Value::Float.cast(value)
18
+ rescue SmartCore::Types::TypeCastingError
19
+ begin
20
+ SmartCore::Types::Value::Integer.cast(value)
21
+ rescue SmartCore::Types::TypeCastingError
22
+ begin
23
+ SmartCore::Types::Value::BigDecimal.cast(value)
24
+ rescue SmartCore::Types::TypeCastingError
25
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Numeric')
26
+ end
27
+ end
15
28
  end
16
29
  end
17
30
  end
@@ -1,11 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
3
5
  # @api public
4
6
  # @since 0.1.0
7
+ # @version 0.3.0
5
8
  SmartCore::Types::Value.define_type(:Proc) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Proc)
8
11
  end
9
12
 
10
- type.define_caster(&:to_proc)
13
+ type.define_caster do |value|
14
+ begin
15
+ value.to_proc.tap do |result|
16
+ unless result.is_a?(::Proc)
17
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Proc')
18
+ end
19
+ end
20
+ rescue ::NoMethodError
21
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Proc')
22
+ end
23
+ end
11
24
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.x.0
5
+ SmartCore::Types::Value.define_type(:Range) do |type|
6
+ type.define_checker do |value|
7
+ # TODO: realize
8
+ end
9
+ end