smart_types 0.1.0.alpha3 → 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 (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc4e623d3f8d313b11dbd7e483989b3f2b94904a9e3a1ec27edb85095fdc418b
4
- data.tar.gz: 3514c7ecfcd83963744f66ce92dfd648bd680b61ad34aaf4c2b0a9207cd842ad
3
+ metadata.gz: d5f0c7f2b54ceaa7fe20e85d7d280b64b8310eb5f4fa802d11052074e6b10f96
4
+ data.tar.gz: 021c3c6194fb4f54246f4a44a7c548ce9da0790a66b95e0a060547e73efeaf3f
5
5
  SHA512:
6
- metadata.gz: a21d4a5a20575cba14a000440c6da87aab465b2aa7c02b2697f13c422fc3c6dbe873c4b2d0fcfec1e5ee182db7a356b8ca0f3bf7beae0f5787b10610d4a3bfca
7
- data.tar.gz: 80c82999c44edab7225b5169cbff0586254c5d817efbfb4c5df4f6906f0b794280dd52c7342fe732b30a6b339c96cf24b40d8c79915a679b87fca9e91a3ac6fa
6
+ metadata.gz: 6e2fc86bcea2292570d2c51e9b95ead6ecc30f8251db75a61fda088c1a84bdb15cea65fdc478728869fb5e5e56b7cddb774938cae38c60e4dee70197e6c1c7f3
7
+ data.tar.gz: c7b27e2f70f3f8eac851f63365b3287a2c7aeb8f7f999679daa715d5ff7de93b32bd6204ea67f6af2c2ea1e5ccd569027051674c9266c62ff7d425c55692619a
@@ -5,7 +5,8 @@ inherit_gem:
5
5
  - lib/rubocop.rspec.yml
6
6
 
7
7
  AllCops:
8
- TargetRubyVersion: 2.4.9
8
+ TargetRubyVersion: 2.7.2
9
+ NewCops: enable
9
10
  Include:
10
11
  - lib/**/*.rb
11
12
  - spec/**/*.rb
@@ -13,3 +14,11 @@ AllCops:
13
14
  - Rakefile
14
15
  - smart_types.gemspec
15
16
  - bin/console
17
+
18
+ # NOTE: support for old ruby versions
19
+ Style/RedundantBegin:
20
+ Enabled: false
21
+
22
+ # NOTE: used only in specs and it is ok in specs
23
+ Lint/EmptyBlock:
24
+ Enabled: false
@@ -2,17 +2,18 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  os: linux
5
- before_install: gem install bundler -v 2.1.2
5
+ dist: xenial
6
+ before_install: gem install bundler
6
7
  script:
7
8
  - bundle exec rake rubocop
8
9
  - bundle exec rake rspec
9
10
  jobs:
10
11
  fast_finish: true
11
12
  include:
12
- - rvm: 2.4.9
13
- - rvm: 2.5.7
14
- - rvm: 2.6.5
15
- - rvm: 2.7.0
13
+ - rvm: 2.4.10
14
+ - rvm: 2.5.8
15
+ - rvm: 2.6.6
16
+ - rvm: 2.7.1
16
17
  - rvm: ruby-head
17
18
  - rvm: jruby-head
18
19
  allow_failures:
@@ -1,2 +1,19 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
+
4
+ ## [0.2.0] - 2020-11-21
5
+ ### Added
6
+ - Brand new **Type invariant API**:
7
+ - globally refactored validation logic (with backward compatability for `#valid?(value)` method);
8
+ - new type definition DSL: `.invariant(name)` and `.invariant_chain(name)`;
9
+ - chained invariants will be invoked according to the definition order (second invokation
10
+ depends on previous successful invariant check);
11
+ - new validation API: `validate(value)` (with `#errors` support based on invariant names);
12
+ - at this moment Invariant API is supported only by primitive types (type sum and type multiplication support coming soon);
13
+
14
+ ### Changed
15
+
16
+ - Updated `smart_engine` dependency (to `~> 0.7`) (need `SmartCore::Engine::Atom`);
17
+
18
+ ## [0.1.0] - 2020-05-05
19
+ - Release :)
@@ -1,77 +1,103 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_types (0.1.0.alpha3)
5
- smart_engine (~> 0.5)
4
+ smart_types (0.2.0)
5
+ smart_engine (~> 0.7)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- armitage-rubocop (0.79.0)
11
- rubocop (= 0.79.0)
12
- rubocop-performance (= 1.5.2)
13
- rubocop-rails (= 2.4.1)
14
- rubocop-rake (= 0.5.0)
15
- rubocop-rspec (= 1.37.1)
16
- ast (2.4.0)
17
- diff-lcs (1.3)
10
+ activesupport (6.0.3.4)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ zeitwerk (~> 2.2, >= 2.2.2)
16
+ armitage-rubocop (1.3.1.1)
17
+ rubocop (= 1.3.1)
18
+ rubocop-performance (= 1.9.0)
19
+ rubocop-rails (= 2.8.1)
20
+ rubocop-rake (= 0.5.1)
21
+ rubocop-rspec (= 2.0.0)
22
+ ast (2.4.1)
23
+ coderay (1.1.3)
24
+ concurrent-ruby (1.1.7)
25
+ diff-lcs (1.4.4)
18
26
  docile (1.3.2)
19
- jaro_winkler (1.5.4)
20
- json (2.3.0)
21
- parallel (1.19.1)
22
- parser (2.7.0.2)
23
- ast (~> 2.4.0)
24
- rack (2.1.1)
27
+ i18n (1.8.5)
28
+ concurrent-ruby (~> 1.0)
29
+ method_source (1.0.0)
30
+ minitest (5.14.2)
31
+ parallel (1.20.0)
32
+ parser (2.7.2.0)
33
+ ast (~> 2.4.1)
34
+ pry (0.13.1)
35
+ coderay (~> 1.1)
36
+ method_source (~> 1.0)
37
+ rack (2.2.3)
25
38
  rainbow (3.0.0)
26
39
  rake (13.0.1)
27
- rspec (3.9.0)
28
- rspec-core (~> 3.9.0)
29
- rspec-expectations (~> 3.9.0)
30
- rspec-mocks (~> 3.9.0)
31
- rspec-core (3.9.1)
32
- rspec-support (~> 3.9.1)
33
- rspec-expectations (3.9.0)
40
+ regexp_parser (1.8.2)
41
+ rexml (3.2.4)
42
+ rspec (3.10.0)
43
+ rspec-core (~> 3.10.0)
44
+ rspec-expectations (~> 3.10.0)
45
+ rspec-mocks (~> 3.10.0)
46
+ rspec-core (3.10.0)
47
+ rspec-support (~> 3.10.0)
48
+ rspec-expectations (3.10.0)
34
49
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-mocks (3.9.1)
50
+ rspec-support (~> 3.10.0)
51
+ rspec-mocks (3.10.0)
37
52
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-support (3.9.2)
40
- rubocop (0.79.0)
41
- jaro_winkler (~> 1.5.1)
53
+ rspec-support (~> 3.10.0)
54
+ rspec-support (3.10.0)
55
+ rubocop (1.3.1)
42
56
  parallel (~> 1.10)
43
- parser (>= 2.7.0.1)
57
+ parser (>= 2.7.1.5)
44
58
  rainbow (>= 2.2.2, < 4.0)
59
+ regexp_parser (>= 1.8)
60
+ rexml
61
+ rubocop-ast (>= 1.1.1)
45
62
  ruby-progressbar (~> 1.7)
46
- unicode-display_width (>= 1.4.0, < 1.7)
47
- rubocop-performance (1.5.2)
48
- rubocop (>= 0.71.0)
49
- rubocop-rails (2.4.1)
63
+ unicode-display_width (>= 1.4.0, < 2.0)
64
+ rubocop-ast (1.1.1)
65
+ parser (>= 2.7.1.5)
66
+ rubocop-performance (1.9.0)
67
+ rubocop (>= 0.90.0, < 2.0)
68
+ rubocop-ast (>= 0.4.0)
69
+ rubocop-rails (2.8.1)
70
+ activesupport (>= 4.2.0)
50
71
  rack (>= 1.1)
51
- rubocop (>= 0.72.0)
52
- rubocop-rake (0.5.0)
72
+ rubocop (>= 0.87.0)
73
+ rubocop-rake (0.5.1)
53
74
  rubocop
54
- rubocop-rspec (1.37.1)
55
- rubocop (>= 0.68.1)
75
+ rubocop-rspec (2.0.0)
76
+ rubocop (~> 1.0)
77
+ rubocop-ast (>= 1.1.0)
56
78
  ruby-progressbar (1.10.1)
57
- simplecov (0.17.1)
79
+ simplecov (0.19.1)
58
80
  docile (~> 1.1)
59
- json (>= 1.8, < 3)
60
- simplecov-html (~> 0.10.0)
61
- simplecov-html (0.10.2)
62
- smart_engine (0.5.0)
63
- unicode-display_width (1.6.0)
81
+ simplecov-html (~> 0.11)
82
+ simplecov-html (0.12.3)
83
+ smart_engine (0.8.0)
84
+ thread_safe (0.3.6)
85
+ tzinfo (1.2.8)
86
+ thread_safe (~> 0.1)
87
+ unicode-display_width (1.7.0)
88
+ zeitwerk (2.4.1)
64
89
 
65
90
  PLATFORMS
66
91
  ruby
67
92
 
68
93
  DEPENDENCIES
69
- armitage-rubocop (~> 0.78)
94
+ armitage-rubocop (~> 1.3)
70
95
  bundler (~> 2.1)
96
+ pry (~> 0.13)
71
97
  rake (~> 13.0)
72
- rspec (~> 3.9)
73
- simplecov (~> 0.17)
98
+ rspec (~> 3.10)
99
+ simplecov (~> 0.19)
74
100
  smart_types!
75
101
 
76
102
  BUNDLED WITH
77
- 2.1.2
103
+ 2.1.4
data/README.md CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  > A set of objects that acts like types (type checking and type casting) with a support for basic type algebra.
4
4
 
5
- Full-featured type system for any ruby project. Supports custom type definitioning,
5
+ Minimalistic type system for any ruby project. Supports custom type definitioning,
6
6
  type validation, type casting and type categorizing. Provides a set of commonly used type
7
7
  categories and general purpose types. Has a flexible and simplest type definition toolchain.
8
8
 
9
- Just add and use :) Enjoy! :)
10
-
11
9
  ## Installation
12
10
 
13
11
  ```ruby
@@ -41,77 +39,349 @@ type4 = type1 & type2
41
39
 
42
40
  ## Supported types
43
41
 
44
- - Primitive Value Types:
42
+ - Primitives
45
43
 
46
44
  ```ruby
47
45
  SmartCore::Types::Value::Any
46
+ SmartCore::Types::Value::Nil
48
47
  SmartCore::Types::Value::String
49
48
  SmartCore::Types::Value::Symbol
50
49
  SmartCore::Types::Value::Text
51
50
  SmartCore::Types::Value::Integer
52
51
  SmartCore::Types::Value::Float
53
52
  SmartCore::Types::Value::Numeric
53
+ SmartCore::Types::Value::BigDecimal
54
54
  SmartCore::Types::Value::Boolean
55
55
  SmartCore::Types::Value::Array
56
56
  SmartCore::Types::Value::Hash
57
57
  SmartCore::Types::Value::Proc
58
58
  SmartCore::Types::Value::Class
59
59
  SmartCore::Types::Value::Module
60
+ SmartCore::Types::Value::Time
61
+ SmartCore::Types::Value::DateTime
62
+ SmartCore::Types::Value::Date
63
+ SmartCore::Types::Value::TimeBased
60
64
  ```
61
65
 
62
66
  ---
63
67
 
64
68
  ## Nilable types
65
69
 
70
+ - invoke `.nilable` on any type object:
71
+
66
72
  ```ruby
67
- SmartCore::Types::Value::Any.nilable
68
73
  SmartCore::Types::Value::String.nilable
69
- SmartCore::Types::Value::Symbol.nilable
70
- SmartCore::Types::Value::Text.nilable
71
- SmartCore::Types::Value::Integer.nilable
72
- SmartCore::Types::Value::Float.nilable
73
- SmartCore::Types::Value::Numeric.nilable
74
- SmartCore::Types::Value::Boolean.nilable
75
- SmartCore::Types::Value::Array.nilable
76
- SmartCore::Types::Value::Hash.nilable
77
- SmartCore::Types::Value::Proc.nilable
78
- SmartCore::Types::Value::Class.nilable
79
- SmartCore::Types::Value::Module.nilable
74
+ # -- or --
75
+ SmartCore::Types::Value::Time.nilable
76
+ # and etc.
80
77
  ```
81
78
 
82
79
  ---
83
80
 
84
- ## Type validation and type casting
81
+ ## Custom type definition
82
+
83
+ Type definition is a composition of:
84
+
85
+ - type checker (required);
86
+ - type caster (optional);
87
+ - type invariants (optional);
88
+ - type invariant chains (optional);
89
+
90
+ Invariant is a custom validation block that will work as a logical value checker. You can have as much invariants as you want.
91
+
92
+ Type invariants does not depends on each other (invariant defined out from chain does not depends on other invariants);
93
+
94
+ Invariants inside invariant chains will be invoked in order they was defined and each internal invariant depends on the valid previous invairant check.
95
+
96
+ **!IMPORTANT!** Type sum and type multiplication does not support invariant checking and custom invariant definitioning at this moment.
97
+ Type sum and type mult ignores type invariants in their validation logic (currently this functionality in development yet).
98
+
99
+ Invariant checking is a special validation layer (see [#type validation](#type-validation) readme section). Invariant error code pattern:
100
+ - for invariant chains: `TypeName.invariant_chain_name.invariant_name`;
101
+ - for single invariant: `TypeName.invariant_name`;
102
+
103
+ #### Primitive type definition
85
104
 
86
105
  ```ruby
87
106
  # documentation is coming
107
+
108
+ # example:
109
+ SmartCore::Types::Value.define_type(:String) do |type|
110
+ type.define_checker do |value|
111
+ value.is_a?(::String)
112
+ end
113
+
114
+ type.define_caster do |value|
115
+ value.to_s
116
+ end
117
+ end
118
+ ```
119
+
120
+ #### With type invariants
121
+
122
+ ```ruby
123
+ SmartCore::Types::Value.define_type(:String) do |type|
124
+ type.define_checker do |value|
125
+ value.is_a?(::String)
126
+ end
127
+
128
+ type.define_caster do |value|
129
+ value.to_s
130
+ end
131
+
132
+ # NOTE:
133
+ # invariant defined out from chain does not depends on other invariants
134
+ type.invariant(:uncensored_content) do |value|
135
+ !value.include?('uncensored_word')
136
+ end
137
+
138
+ type.invariant(:filled) do |value|
139
+ value != ''
140
+ end
141
+
142
+ type.invariant_chain(:password) do
143
+ invariant(:should_present) { |value| value != '' }
144
+ invariant(:should_have_numbers) { |value| v.match?(/[0-9]+/) }
145
+ # NOTE:
146
+ # inside a chain each next invariant invokation
147
+ # depends on previous successful invariant check
148
+ end
149
+ end
88
150
  ```
89
151
 
90
152
  ---
91
153
 
92
- ## Custom type definition
154
+ ## Type validation
155
+
156
+ Type validation reflects on two APIs:
157
+
158
+ - type checker ([how to define type checkers](#custom-type-definition));
159
+ - type invariants (invariants and invariant chains) ([how to define type invariants](#custom-type-definition));
160
+
161
+ Type invariants does not depends on each other (invariant defined out from the chain does not depends on other invariants);
162
+
163
+ Invariants inside invariant chains will be invoked in order they was defined and each internal invariant depends on the valid previous invairant check.
164
+
165
+ **!IMPORTANT!** Type sum and type multiplication does not support invariant checking and custom invariant definitioning at this moment.
166
+ Type sum and type mult ignores type invariants in their validation logic (currently this functionality in development yet).
167
+
168
+ Invariant checking is a special validation layer (see [#type validation](#type-validation) readme section) and represents a set of error codes in result object;
169
+
170
+ Type valdiation interface:
171
+
172
+ - `valid?(value)` - validates value and returns `true` or `false`;
173
+ - returns `ture` only if the type checker returns `true` and all invariants are valid;
174
+ - `validate(value)` - validates value and returns the monadic result object:
175
+ - `SmartCore::Types::Primitive::Validator::Result` for primitive types;
176
+ - `SmartCore::Types::Primitive::SumValidator::Result` for sum-based types;
177
+ - `SmartCore::Types::Primitive::MultValidator::Result` for mult-based types;
178
+ - `SmartCore::Types::Primitive::NilableValidator::Result` for nilable types;
179
+ - `validate!(value)` - validates value and returns nothing (for successful validation) or
180
+ raises an exception (`SmartCore::Types::TypeError`) (for unsuccessful validation);
181
+
182
+ Validation result object interface:
183
+
184
+ - `#success?` / `#failure?` (`#success?` is a combination of `valid_check? && valid_invariants?`; `#failure?` - is an opposite of `#success?`);
185
+ - `#valid_check?` (valid type checker or not);
186
+ - `#valid_invariants?` (`false` if at least one invariant is invalid);
187
+ - `#errors` (the same as `#invariant_errors` and the same as `#error_codes`) - an array of failed invariant names;
188
+ - error code patterns:
189
+ - for invariant chains: `TypeName.invariant_chain_name.invariant_name`;
190
+ - for single invariant: `TypeName.invariant_name`;
191
+ - `#checked_value` (the same as `#value`) - checked value :)
192
+
93
193
 
94
194
  ```ruby
95
- # documentation is coming
195
+ SmartCore::Types::Value::String.valid?('test123') # => true
196
+ SmartCore::Types::Value::String.valid?(123.45) # => false
197
+ ```
198
+
199
+ ```ruby
200
+ result = SmartCore::Types::Value::String.validate('test')
201
+
202
+ result.checked_value # => 'test'
203
+ # --- same as: ---
204
+ result.value
205
+
206
+ result.success? # => false (valid_check? && valid_invariants?)
207
+ result.failure? # => true
208
+
209
+ result.valid_check? # => true
210
+ result.valid_invariants? # => false
211
+
212
+ # invariant errors:
213
+ result.errors # => ['String.password.should_have_numbers']
214
+ # -- same as: ---
215
+ result.invariant_errors
216
+ # -- same as: ---
217
+ result.error_codes
218
+ ```
219
+
220
+ ```ruby
221
+ result = SmartCore::Types::Value::String.validate('test1234')
222
+ result.success? # => true
223
+ result.errors # => []
224
+ ```
225
+
226
+ ```ruby
227
+ SmartCore::Types::Value::String.validate!('test') # => SmartCore::Types::TypeError
228
+ ```
229
+
230
+ ---
231
+
232
+ ## Type casting
233
+
234
+ ```
235
+ SmartCore::Types::Value::String.cast(123) # => "123"
236
+ SmartCore::Types::Value::Float.cast('55') # => 55.0
96
237
  ```
97
238
 
98
239
  ---
99
240
 
100
241
  ## Basic type algebra
101
242
 
243
+ > (type sum and type multiplication does not support invariants at this moment (in development yet));
244
+
102
245
  ```ruby
103
246
  # documentation is coming
247
+
248
+ # how to define primitive type sum:
249
+ SmartCore::Types::Value::Text = SmartCore::Types::Value::String | SmartCore::Types::Value::Symbol
250
+ SmartCore::Types::Value::Numeric = SmartCore::Types::Value::Float | SmartCore::Types::Value::Integer
251
+
252
+ # how to define primitive type multiplication:
253
+ SmartCore::Types::Value::CryptoString = SmartCore::Types::Value::NumberdString & SmartCore::Types::Value::SymbolicString
104
254
  ```
105
255
 
106
256
  ---
107
257
 
108
- ## Type system integration
258
+ ## Roadmap
259
+
260
+ - type configuration:
109
261
 
110
262
  ```ruby
111
- # documentation is coming
263
+ SmartCore::Types::Value.type(:Time) do |type|
264
+ type.configuration do |config| # config definition
265
+ setting :iso, :rfc2822
266
+ # TODO: think about a more convinient DSL
267
+ end
268
+
269
+ type.define_caster do |value, config| # config usage
270
+ case config.standard
271
+ when :rfc2822
272
+ ::Time.rfc2822(value)
273
+ else
274
+ # ...
275
+ end
276
+ end
277
+ end
112
278
  ```
113
279
 
114
- ---
280
+ - pipelined type caster definition for the sum-based types:
281
+
282
+ ```ruby
283
+ SmartCore::Types::Value::TimeLike = SmartCore::Types::System.type_sum(
284
+ SmartCore::Types::Time,
285
+ SmartCore::Types::DateTime,
286
+ SmartCore::Types::Date,
287
+ ) do |type|
288
+ type.define_caster(:pipelined) # try Time.cast => try DateTime.cast => try Date.cast
289
+ end
290
+ ```
291
+
292
+ - namespaced type errors:
293
+
294
+ ```ruby
295
+ # before:
296
+ SmartCore::Types::Value::Boolean.validate!(123)
297
+ # => SmartCore::Types::TypeError
298
+ SmartCore::Types::Value::Class.cast(123)
299
+ # => SmartCore::Types::TypeCastingError
300
+
301
+ # after:
302
+ SmartCore::Types::Value::Boolean.validate!(123)
303
+ # => SmartCore::Types::Value::Boolean::TypeError
304
+ # (inheritance tree: Types::Value::<Type>::TypeError => Types::Value::TypeError => Types::TypeError)
305
+
306
+ SmartCore::Types::Value::Class.cast(123)
307
+ # => SmartCore::Types::Value::Class::TypeCastingError
308
+ # (inheritance tree: the same as above)
309
+ ```
310
+
311
+ - type refinements:
312
+
313
+ ```ruby
314
+ SmartCore::Types::Value::Time.refine_checker do |value, original_checker|
315
+ # new type checker
316
+ end
317
+
318
+ SmartCore::Types::Value::Time.refine_caster do |value, original_caster|
319
+ # new type caster
320
+ end
321
+
322
+ # .refine_invariant
323
+ # .refine_invariant_chain
324
+ ```
325
+
326
+ - options for type casters:
327
+
328
+ ```ruby
329
+ SmartCore::Types::Value.define_type(:Date) do |type|
330
+ type.define_caster do |value, options = {}| # options goes here
331
+ iso = options.fetch(:iso, nil)
332
+ iso ? ::Date.pasre(value, iso) : ::Date.parse(value)
333
+ end
334
+ end
335
+
336
+ # usage:
337
+ SmartCore::Types::Value::Date.cast('2020-01-01', { iso: :rfc3339 })
338
+ ```
339
+
340
+ - new types:
341
+
342
+ ```ruby
343
+ SmartCore::Types::Value::Method
344
+ SmartCore::Types::Value::UnboundMethod
345
+ SmartCore::Types::Value::Enumerable
346
+ SmartCore::Types::Value::Comparable
347
+ SmartCore::Types::Value::Enumerator
348
+ SmartCore::Types::Value::EnumeratorChain
349
+ SmartCore::Types::Value::Range
350
+ SmartCore::Types::Value::Rational
351
+ SmartCore::Types::Value::Set
352
+ SmartCore::Types::Value::SortedSet
353
+ SmartCore::Types::Value::IO
354
+ SmartCore::Types::Value::StringIO
355
+ SmartCore::Types::Struct::Schema
356
+ SmartCore::Types::Struct::JSONSchema
357
+ SmartCore::Types::Struct::StrictArray
358
+ SmartCore::Types::Struct::StrictHash
359
+ SmartCore::Types::Struct::Map
360
+ SmartCore::Types::Variative::Enum
361
+ SmartCore::Types::Variative::Variant
362
+ SmartCore::Types::Protocol::InstanceOf
363
+ SmartCore::Types::Protocol::Interface
364
+ SmartCore::Types::Protocol::Ancestors
365
+ SmartCore::Types::Protocol::Enumerable
366
+ SmartCore::Types::Protocol::Comparable
367
+ SmartCore::Types::Protocol::Forwardable
368
+ SmartCore::Types::Protocol::Callable
369
+ ```
370
+
371
+ - support for type of empty non-defined type (`SmartCore::Types::Primitive::Undefined`);
372
+ - constrained types;
373
+ - moudle-based type system integration;
374
+ - constructor implementation and support;
375
+ - support for invariant checking (and custom definitioning) in sum-types;
376
+ - to provide a type comparability and compatability between all passed types
377
+ you should provide `type.reconcilable { |value, *types| .... }` setting;
378
+ - `type.reconcilable` should be accesible for type sum and type mult definitions;
379
+ - (**preliminarily**) invariants of the concrete passed type should be valid for sucessful invariant check;
380
+ - support for invariant checking (and definitioning) in mult-types;
381
+ - to provide a type comparability and compatability between all passed types
382
+ you should provide `type.reconcilable { |value, *types| .... }` setting;
383
+ - `type.reconcilable` should be accesible for type sum and type mult definitions;
384
+ - (**preliminarily**) all invariants of all types should be valid for sucessful invariant check;
115
385
 
116
386
  ## Contributing
117
387