smart_types 0.1.0.alpha5 → 0.4.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 (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