smart_types 0.2.0 → 0.3.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/Gemfile.lock +33 -32
  4. data/README.md +161 -16
  5. data/lib/smart_core/types.rb +2 -0
  6. data/lib/smart_core/types/errors.rb +12 -0
  7. data/lib/smart_core/types/primitive.rb +49 -4
  8. data/lib/smart_core/types/primitive/caster.rb +5 -2
  9. data/lib/smart_core/types/primitive/checker.rb +5 -2
  10. data/lib/smart_core/types/primitive/factory.rb +64 -6
  11. data/lib/smart_core/types/primitive/factory/definition_context.rb +37 -11
  12. data/lib/smart_core/types/primitive/factory/runtime_type_builder.rb +53 -0
  13. data/lib/smart_core/types/primitive/invariant_control.rb +6 -3
  14. data/lib/smart_core/types/primitive/invariant_control/chain.rb +5 -2
  15. data/lib/smart_core/types/primitive/invariant_control/single.rb +5 -2
  16. data/lib/smart_core/types/primitive/mult_factory.rb +40 -6
  17. data/lib/smart_core/types/primitive/mult_factory/definition_context.rb +23 -1
  18. data/lib/smart_core/types/primitive/mult_validator.rb +8 -0
  19. data/lib/smart_core/types/primitive/nilable_factory.rb +10 -3
  20. data/lib/smart_core/types/primitive/runtime_attributes_checker.rb +77 -0
  21. data/lib/smart_core/types/primitive/sum_factory.rb +40 -6
  22. data/lib/smart_core/types/primitive/sum_factory/definition_context.rb +23 -1
  23. data/lib/smart_core/types/primitive/sum_validator.rb +18 -2
  24. data/lib/smart_core/types/primitive/undefined_caster.rb +4 -1
  25. data/lib/smart_core/types/primitive/validator.rb +16 -7
  26. data/lib/smart_core/types/protocol.rb +7 -0
  27. data/lib/smart_core/types/protocol/instance_of.rb +19 -0
  28. data/lib/smart_core/types/value/array.rb +3 -0
  29. data/lib/smart_core/types/value/big_decimal.rb +4 -1
  30. data/lib/smart_core/types/value/boolean.rb +3 -0
  31. data/lib/smart_core/types/value/class.rb +3 -0
  32. data/lib/smart_core/types/value/date.rb +3 -0
  33. data/lib/smart_core/types/value/date_time.rb +3 -0
  34. data/lib/smart_core/types/value/enumerable.rb +1 -1
  35. data/lib/smart_core/types/value/float.rb +3 -0
  36. data/lib/smart_core/types/value/hash.rb +3 -0
  37. data/lib/smart_core/types/value/integer.rb +3 -0
  38. data/lib/smart_core/types/value/module.rb +3 -0
  39. data/lib/smart_core/types/value/numeric.rb +3 -0
  40. data/lib/smart_core/types/value/proc.rb +3 -0
  41. data/lib/smart_core/types/value/set.rb +11 -3
  42. data/lib/smart_core/types/value/string.rb +3 -0
  43. data/lib/smart_core/types/value/string_io.rb +2 -0
  44. data/lib/smart_core/types/value/symbol.rb +3 -0
  45. data/lib/smart_core/types/value/text.rb +6 -4
  46. data/lib/smart_core/types/value/time.rb +3 -0
  47. data/lib/smart_core/types/value/time_based.rb +8 -5
  48. data/lib/smart_core/types/variadic.rb +7 -0
  49. data/lib/smart_core/types/variadic/tuple.rb +23 -0
  50. data/lib/smart_core/types/version.rb +2 -2
  51. data/smart_types.gemspec +3 -3
  52. metadata +15 -10
  53. data/.travis.yml +0 -21
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::SumValidator
6
7
  require_relative 'sum_validator/result'
7
8
 
@@ -15,6 +16,17 @@ class SmartCore::Types::Primitive::SumValidator
15
16
  @validators = validators
16
17
  end
17
18
 
19
+ # @param type [SmartCore::Types::Primitive]
20
+ # @return [SmartCore::Types::Primitive::SumValidator]
21
+ #
22
+ # @api private
23
+ # @since 0.3.0
24
+ def ___copy_for___(type)
25
+ self.class.new(type_checker, invariant_control).tap do |instance_copy|
26
+ instance_copy.___assign_type___(type)
27
+ end
28
+ end
29
+
18
30
  # @param type [SmartCore::Types::Primitive]
19
31
  # @return [void]
20
32
  #
@@ -28,11 +40,14 @@ class SmartCore::Types::Primitive::SumValidator
28
40
  #
29
41
  # @api private
30
42
  # @since 0.2.0
43
+ # @version 0.3.0
31
44
  def valid?(value)
32
45
  # NOTE: at this moment type sum does not support invariant checking
33
46
  # TODO (0.x.0):
34
47
  # validators.any? { |validator| validator.valid?(value) }
35
- validators.any? { |validator| validator.type_checker.call(value) }
48
+ validators.any? do |validator|
49
+ validator.type_checker.call(value, type.runtime_attributes)
50
+ end
36
51
  end
37
52
 
38
53
  # @param value [Any]
@@ -40,6 +55,7 @@ class SmartCore::Types::Primitive::SumValidator
40
55
  #
41
56
  # @api private
42
57
  # @since 0.2.0
58
+ # @version 0.3.0
43
59
  def validate(value)
44
60
  compile_validation_result do
45
61
  SmartCore::Engine::Atom.new.tap do |result|
@@ -48,7 +64,7 @@ class SmartCore::Types::Primitive::SumValidator
48
64
  # TODO (0.x.0):
49
65
  # result.swap { validator.validate(value) }
50
66
  # break if result.value.success?
51
- result.swap { validator.type_checker.call(value) }
67
+ result.swap { validator.type_checker.call(value, type.runtime_attributes) }
52
68
  break if result.value # => boolean
53
69
  end
54
70
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::UndefinedCaster < SmartCore::Types::Primitive::Caster
6
7
  # @param expression [NilClass, Any]
7
8
  # @return [void]
@@ -13,13 +14,15 @@ class SmartCore::Types::Primitive::UndefinedCaster < SmartCore::Types::Primitive
13
14
  end
14
15
 
15
16
  # @param value [Any]
17
+ # @param runtime_attributes [Array<Any>]
16
18
  # @return [void]
17
19
  #
18
20
  # @raise [SmartCore::Types::TypeCastingUnsupportedError]
19
21
  #
20
22
  # @pai private
21
23
  # @since 0.1.0
22
- def call(value)
24
+ # @version 0.3.0
25
+ def call(value, runtime_attributes)
23
26
  raise(SmartCore::Types::TypeCastingUnsupportedError, <<~ERROR_MESSAGE)
24
27
  'This type has no support for type casting'
25
28
  ERROR_MESSAGE
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.2.0
5
+ # @version 0.3.0
5
6
  class SmartCore::Types::Primitive::Validator
6
7
  require_relative 'validator/result'
7
8
 
@@ -23,11 +24,7 @@ class SmartCore::Types::Primitive::Validator
23
24
  # @since 0.2.0
24
25
  attr_reader :invariant_control
25
26
 
26
- # @param type_checker [
27
- # SmartCore::Types::Primitive::Checker,
28
- # SmartCore::Types::Primitive::MultChecker,
29
- # SmartCore::Types::Primitive::SumChecker
30
- # ]
27
+ # @param type_checker [SmartCore::Types::Primitive::Checker]
31
28
  # @param invariant_control [SmartCore::Types::Primitive::InvariantControl]
32
29
  # @return [void]
33
30
  #
@@ -39,6 +36,17 @@ class SmartCore::Types::Primitive::Validator
39
36
  @invariant_control = invariant_control
40
37
  end
41
38
 
39
+ # @param type [SmartCore::Types::Primitive]
40
+ # @return [SmartCore::Types::Primitive::Validator]
41
+ #
42
+ # @api private
43
+ # @since 0.3.0
44
+ def ___copy_for___(type)
45
+ self.class.new(type_checker, invariant_control).tap do |instance_copy|
46
+ instance_copy.___assign_type___(type)
47
+ end
48
+ end
49
+
42
50
  # @param type [SmartCore::Types::Primitive]
43
51
  # @return [void]
44
52
  #
@@ -62,10 +70,11 @@ class SmartCore::Types::Primitive::Validator
62
70
  #
63
71
  # @api private
64
72
  # @since 0.2.0
73
+ # @version 0.3.0
65
74
  def validate(value)
66
- checker_result = type_checker.call(value) # => Boolean
75
+ checker_result = type_checker.call(value, type.runtime_attributes) # => Boolean
67
76
  return Result.new(type, value, checker_result) unless checker_result
68
- invariant_result = invariant_control.check(value)
77
+ invariant_result = invariant_control.check(value, type.runtime_attributes)
69
78
  invariant_errors = invariant_result.invariant_errors.map { |error| "#{type.name}.#{error}" }
70
79
  Result.new(type, value, checker_result, invariant_errors)
71
80
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.3.0
5
+ class SmartCore::Types::Protocol < SmartCore::Types::Primitive
6
+ require_relative 'protocol/instance_of'
7
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
5
+ # @api public
6
+ # @since 0.3.0
7
+ SmartCore::Types::Protocol.define_type(:InstanceOf) do |type|
8
+ type.runtime_attributes_checker do |runtime_attrs|
9
+ runtime_attrs.any? && runtime_attrs.all? do |runtime_attr|
10
+ runtime_attr.is_a?(::Class)
11
+ end
12
+ end
13
+
14
+ type.define_checker do |value, expected_types|
15
+ expected_types.any? && expected_types.any? do |expected_type|
16
+ value.is_a?(expected_type)
17
+ end
18
+ end
19
+ 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)
@@ -3,15 +3,18 @@
3
3
  require 'bigdecimal'
4
4
  require 'bigdecimal/util'
5
5
 
6
+ using SmartCore::Ext::BasicObjectAsObject
7
+
6
8
  # @api public
7
9
  # @since 0.1.0
10
+ # @version 0.3.0
8
11
  SmartCore::Types::Value.define_type(:BigDecimal) do |type|
9
12
  type.define_checker do |value|
10
13
  value.is_a?(::BigDecimal)
11
14
  end
12
15
 
13
16
  type.define_caster do |value|
14
- if SmartCore::Types::Value::Float.valid?(value)
17
+ if SmartCore::Types::Value::Numeric.valid?(value)
15
18
  value = SmartCore::Types::Value::String.cast(value)
16
19
  end
17
20
 
@@ -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)
@@ -2,8 +2,11 @@
2
2
 
3
3
  require 'date'
4
4
 
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
5
7
  # @api public
6
8
  # @since 0.1.0
9
+ # @version 0.3.0
7
10
  SmartCore::Types::Value.define_type(:Date) do |type|
8
11
  type.define_checker do |value|
9
12
  value.is_a?(::Date) || value == ::Date::Infinity
@@ -2,8 +2,11 @@
2
2
 
3
3
  require 'date'
4
4
 
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
5
7
  # @api public
6
8
  # @since 0.1.0
9
+ # @version 0.3.0
7
10
  SmartCore::Types::Value.define_type(:DateTime) do |type|
8
11
  type.define_checker do |value|
9
12
  value.is_a?(::DateTime) || value == ::DateTime::Infinity
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # @api public
4
- # @since 0.1.0
4
+ # @since 0.x.0
5
5
  SmartCore::Types::Value.define_type(:Enumerable) do |type|
6
6
  type.define_checker do |value|
7
7
  # TODO: realize
@@ -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)
@@ -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)
@@ -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)
@@ -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,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(:Numeric) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Numeric)
@@ -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(:Proc) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Proc)
@@ -1,13 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
3
7
  # @api public
4
- # @since 0.x.0
8
+ # @since 0.3.0
5
9
  SmartCore::Types::Value.define_type(:Set) do |type|
6
10
  type.define_checker do |value|
7
- # TODO: realize
11
+ value.is_a?(::Set)
8
12
  end
9
13
 
10
14
  type.define_caster do |value|
11
- # TODO: realize
15
+ begin
16
+ ::Set.new(SmartCore::Types::Value::Array.cast(value))
17
+ rescue ::ArgumentError, ::NoMethodError
18
+ raise(SmartCore::Types::TypeCastingError, 'Non-castable to Set')
19
+ end
12
20
  end
13
21
  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(:String) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::String)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'stringio'
4
+
3
5
  # @api public
4
6
  # @since 0.x.0
5
7
  SmartCore::Types::Value.define_type(:StringIO) do |type|
@@ -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(:Symbol) do |type|
6
9
  type.define_checker do |value|
7
10
  value.is_a?(::Symbol)
@@ -2,10 +2,12 @@
2
2
 
3
3
  # @api public
4
4
  # @since 0.1.0
5
- SmartCore::Types::Value::Text = SmartCore::Types::System.type_sum(
6
- SmartCore::Types::Value::String,
7
- SmartCore::Types::Value::Symbol
8
- ) do |type|
5
+ # @version 0.3.0
6
+ SmartCore::Types::Value.define_type(:Text) do |type|
7
+ type.define_checker do |value|
8
+ SmartCore::Types::Value::String.valid?(value) || SmartCore::Types::Value::Symbol.valid?(value)
9
+ end
10
+
9
11
  type.define_caster do |value|
10
12
  next value if SmartCore::Types::Value::String.valid?(value)
11
13
  next value if SmartCore::Types::Value::Symbol.valid?(value)
@@ -2,8 +2,11 @@
2
2
 
3
3
  require 'time'
4
4
 
5
+ using SmartCore::Ext::BasicObjectAsObject
6
+
5
7
  # @api public
6
8
  # @since 0.1.0
9
+ # @version 0.3.0
7
10
  SmartCore::Types::Value.define_type(:Time) do |type|
8
11
  type.define_checker do |value|
9
12
  value.is_a?(::Time)
@@ -2,11 +2,14 @@
2
2
 
3
3
  # @api public
4
4
  # @since 0.1.0
5
- SmartCore::Types::Value::TimeBased = SmartCore::Types::System.type_sum(
6
- SmartCore::Types::Value::Time,
7
- SmartCore::Types::Value::DateTime,
8
- SmartCore::Types::Value::Date
9
- ) do |type|
5
+ # @version 0.3.0
6
+ SmartCore::Types::Value.define_type(:TimeBased) do |type|
7
+ type.define_checker do |value|
8
+ SmartCore::Types::Value::Time.valid?(value) ||
9
+ SmartCore::Types::Value::DateTime.valid?(value) ||
10
+ SmartCore::Types::Value::Date.valid?(value)
11
+ end
12
+
10
13
  type.define_caster do |value|
11
14
  next value if SmartCore::Types::Value::Time.valid?(value)
12
15
  next value if SmartCore::Types::Value::DateTime.valid?(value)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.3.0
5
+ class SmartCore::Types::Variadic < SmartCore::Types::Primitive
6
+ require_relative 'variadic/tuple'
7
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ using SmartCore::Ext::BasicObjectAsObject
4
+
5
+ # @api public
6
+ # @since 0.3.0
7
+ SmartCore::Types::Variadic.define_type(:Tuple) do |type|
8
+ type.runtime_attributes_checker do |runtime_attrs|
9
+ runtime_attrs.any? && runtime_attrs.all? do |runtime_attr|
10
+ runtime_attr.is_a?(::Class)
11
+ end
12
+ end
13
+
14
+ type.define_checker do |value, tuple_signature|
15
+ next false unless SmartCore::Types::Value::Array.valid?(value)
16
+ next false if value.size != tuple_signature.size
17
+
18
+ value.each_with_index.all? do |tuple_val, tuple_val_index|
19
+ expected_tuple_type = tuple_signature.at(tuple_val_index)
20
+ tuple_val.is_a?(expected_tuple_type)
21
+ end
22
+ end
23
+ end