smart_initializer 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +35 -3
  4. data/Gemfile.lock +38 -38
  5. data/README.md +260 -46
  6. data/bin/console +2 -2
  7. data/gemfiles/with_external_deps.gemfile.lock +38 -38
  8. data/lib/smart_core/initializer/attribute/factory/base.rb +145 -0
  9. data/lib/smart_core/initializer/attribute/factory/option.rb +107 -0
  10. data/lib/smart_core/initializer/attribute/factory/param.rb +63 -0
  11. data/lib/smart_core/initializer/attribute/factory.rb +5 -199
  12. data/lib/smart_core/initializer/attribute/finalizer/abstract.rb +2 -0
  13. data/lib/smart_core/initializer/attribute/finalizer/instance_method.rb +1 -1
  14. data/lib/smart_core/initializer/attribute/finalizer.rb +5 -5
  15. data/lib/smart_core/initializer/attribute/list.rb +20 -0
  16. data/lib/smart_core/initializer/attribute/{parameters.rb → value/base.rb} +35 -65
  17. data/lib/smart_core/initializer/attribute/value/option.rb +101 -0
  18. data/lib/smart_core/initializer/attribute/value/param.rb +24 -0
  19. data/lib/smart_core/initializer/attribute/value.rb +9 -0
  20. data/lib/smart_core/initializer/attribute.rb +3 -125
  21. data/lib/smart_core/initializer/configuration.rb +7 -3
  22. data/lib/smart_core/initializer/constructor/definer.rb +135 -46
  23. data/lib/smart_core/initializer/constructor.rb +30 -12
  24. data/lib/smart_core/initializer/dsl.rb +38 -24
  25. data/lib/smart_core/initializer/errors.rb +20 -4
  26. data/lib/smart_core/initializer/functionality.rb +7 -8
  27. data/lib/smart_core/initializer/settings/auto_cast.rb +40 -0
  28. data/lib/smart_core/initializer/settings/base.rb +49 -0
  29. data/lib/smart_core/initializer/settings/duplicator.rb +5 -0
  30. data/lib/smart_core/initializer/settings/strict_options.rb +40 -0
  31. data/lib/smart_core/initializer/settings/type_system.rb +10 -28
  32. data/lib/smart_core/initializer/settings.rb +40 -0
  33. data/lib/smart_core/initializer/type_system/registry.rb +2 -1
  34. data/lib/smart_core/initializer/type_system/smart_types.rb +2 -2
  35. data/lib/smart_core/initializer/version.rb +2 -2
  36. data/lib/smart_core/initializer.rb +14 -4
  37. data/smart_initializer.gemspec +2 -2
  38. metadata +16 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84aa6ce59c1c73432c01015a595c6a20c2e11344d2d6464aa63920c288f3b51f
4
- data.tar.gz: '0819287ddbd9cfc21fac709a848205230036dd2b724df4568ed90b36bbd0316e'
3
+ metadata.gz: e16ae20c546597ce7c44382a790934260b44b1ebff59a51c7c7eb366205d969f
4
+ data.tar.gz: 14af5a449ae56ecf8b38d22c3ea0957f4896070556fec3c280a4b265e78f63de
5
5
  SHA512:
6
- metadata.gz: e6b1f6664ae3e519b4fe516e565b959987f459d145d0f5de4a7d26e8b9d32ed103567eb11d7d050ef1b3d7ad2fa05e430223060f7638552dfe24edd3d8999644
7
- data.tar.gz: 7ee572ea83d433095f1fd3a27a127543eb22fbbafde515e052e6d1a3360914c828a8dd983f8659501a7fbca08499cec11a34a18e4c43ac9702acd39af5235663
6
+ metadata.gz: cecc3bc1e93570d2c8cb0cc11c1b409c24d6b401a9a8225de4676a10915c7e08a1bf869315650f9ddf66c7b5dc4602e96d2a0717a83289b6fec79cb795d5dde9
7
+ data.tar.gz: 6ed53102d9c016fbdad65a3f4ad2b2aec6ad567596ec3e255f33a55f979eab5180138ae496f1ff5eafae3ae71019229ea8840d9fc1608ddcbb821a6f2aeffae5
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ inherit_gem:
5
5
  - lib/rubocop.rspec.yml
6
6
 
7
7
  AllCops:
8
- TargetRubyVersion: 3.0.0
8
+ TargetRubyVersion: 3.1
9
9
  NewCops: enable
10
10
  Include:
11
11
  - lib/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,16 +1,48 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.8.0] - 2021-12-04
5
+ ### Added
6
+ - New options for option and param attributes:
7
+ - Support for attribute **aliasing** (`:as` parameter);
8
+ - supports: `option`, `param`;
9
+ - Support for attribute **auto-casting** (`:auto_cast` parameter);
10
+ - supports: `option`, `param`;
11
+ - Support for **mutable** attributes (`:mutable` parameter) with type-validation inside;
12
+ - supports: `option`, `options`, `param`, `params`;
13
+ - Support for **optional** attributes (`:optional` parameter);
14
+ - supports: `option`;
15
+ - **SmartCore::Initializer::Configuration**:
16
+ - Configuration setting `strict_options` now works separately "per-class" in all configs manner
17
+ (each class shares the global state but has own state too)
18
+ - Support for per-class/global `:auto_cast` configuration;
19
+ - provides a global/per-class behavior for `:cast` option (`false` by default);
20
+ - `options` declaration now supports `privacy` option;
21
+ - `params` declaration now supports `privacy` option;
22
+
23
+ ### Changed
24
+ - Drop support of **Ruby@2.4**;
25
+ - `:default` attribute parameter now duplicates the passed value during object instantiation;
26
+ - `:default` attribute parameter only works with `option` attribute (`param` can't have `default` parameter now);
27
+ - Attribute values generated by `:finalize` are type-validated now too;
28
+ - Now lambda-based `:finalize` attributes are being checked for the signature during attribute declaration;
29
+ - Some error messages have become more readable;
30
+
31
+ ## Fixed
32
+ - `send` method overlaping/rewriting: otions and params named as `send` breaks the internal
33
+ framework-related invocations of the attribute definitioning inside the custom object constructor
34
+ (this name rewrites internal Ruby's `send` method and brokes some things);
35
+
4
36
  ## [0.7.0] - 2021-06-23
5
- ## Added
37
+ ### Added
6
38
  - `strict_options` config option for non-strict checking of passed options;
7
39
 
8
40
  ## [0.6.0] - 2021-06-23
9
- ## Added
41
+ ### Added
10
42
  - Validation messages for incorrect attribute types;
11
43
 
12
44
  ## [0.5.0] - 2021-01-18
13
- ## Changed
45
+ ### Changed
14
46
  - Updated `smart_types` dependency (`~> 0.4.0`) to guarantee **Ruby@3** compatibility;
15
47
  - Updated development dependencies;
16
48
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_initializer (0.6.1)
4
+ smart_initializer (0.8.0)
5
5
  qonfig (~> 0.24)
6
6
  smart_engine (~> 0.11)
7
7
  smart_types (~> 0.4)
@@ -9,39 +9,39 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activesupport (6.1.2)
12
+ activesupport (6.1.4.1)
13
13
  concurrent-ruby (~> 1.0, >= 1.0.2)
14
14
  i18n (>= 1.6, < 2)
15
15
  minitest (>= 5.1)
16
16
  tzinfo (~> 2.0)
17
17
  zeitwerk (~> 2.3)
18
- armitage-rubocop (1.8.1)
19
- rubocop (= 1.8.1)
20
- rubocop-performance (= 1.9.2)
21
- rubocop-rails (= 2.9.1)
22
- rubocop-rake (= 0.5.1)
23
- rubocop-rspec (= 2.1.0)
18
+ armitage-rubocop (1.23.0.1)
19
+ rubocop (= 1.23.0)
20
+ rubocop-performance (= 1.12.0)
21
+ rubocop-rails (= 2.12.4)
22
+ rubocop-rake (= 0.6.0)
23
+ rubocop-rspec (= 2.6.0)
24
24
  ast (2.4.2)
25
25
  coderay (1.1.3)
26
- concurrent-ruby (1.1.8)
26
+ concurrent-ruby (1.1.9)
27
27
  diff-lcs (1.4.4)
28
- docile (1.3.5)
29
- i18n (1.8.8)
28
+ docile (1.4.0)
29
+ i18n (1.8.11)
30
30
  concurrent-ruby (~> 1.0)
31
31
  method_source (1.0.0)
32
- minitest (5.14.3)
33
- parallel (1.20.1)
34
- parser (3.0.0.0)
32
+ minitest (5.14.4)
33
+ parallel (1.21.0)
34
+ parser (3.0.3.1)
35
35
  ast (~> 2.4.1)
36
- pry (0.14.0)
36
+ pry (0.14.1)
37
37
  coderay (~> 1.1)
38
38
  method_source (~> 1.0)
39
- qonfig (0.25.0)
39
+ qonfig (0.26.0)
40
40
  rack (2.2.3)
41
41
  rainbow (3.0.0)
42
- rake (13.0.3)
43
- regexp_parser (2.0.3)
44
- rexml (3.2.4)
42
+ rake (13.0.6)
43
+ regexp_parser (2.2.0)
44
+ rexml (3.2.5)
45
45
  rspec (3.10.0)
46
46
  rspec-core (~> 3.10.0)
47
47
  rspec-expectations (~> 3.10.0)
@@ -54,51 +54,51 @@ GEM
54
54
  rspec-mocks (3.10.2)
55
55
  diff-lcs (>= 1.2.0, < 2.0)
56
56
  rspec-support (~> 3.10.0)
57
- rspec-support (3.10.2)
58
- rubocop (1.8.1)
57
+ rspec-support (3.10.3)
58
+ rubocop (1.23.0)
59
59
  parallel (~> 1.10)
60
60
  parser (>= 3.0.0.0)
61
61
  rainbow (>= 2.2.2, < 4.0)
62
62
  regexp_parser (>= 1.8, < 3.0)
63
63
  rexml
64
- rubocop-ast (>= 1.2.0, < 2.0)
64
+ rubocop-ast (>= 1.12.0, < 2.0)
65
65
  ruby-progressbar (~> 1.7)
66
66
  unicode-display_width (>= 1.4.0, < 3.0)
67
- rubocop-ast (1.4.1)
68
- parser (>= 2.7.1.5)
69
- rubocop-performance (1.9.2)
70
- rubocop (>= 0.90.0, < 2.0)
67
+ rubocop-ast (1.14.0)
68
+ parser (>= 3.0.1.1)
69
+ rubocop-performance (1.12.0)
70
+ rubocop (>= 1.7.0, < 2.0)
71
71
  rubocop-ast (>= 0.4.0)
72
- rubocop-rails (2.9.1)
72
+ rubocop-rails (2.12.4)
73
73
  activesupport (>= 4.2.0)
74
74
  rack (>= 1.1)
75
- rubocop (>= 0.90.0, < 2.0)
76
- rubocop-rake (0.5.1)
77
- rubocop
78
- rubocop-rspec (2.1.0)
75
+ rubocop (>= 1.7.0, < 2.0)
76
+ rubocop-rake (0.6.0)
79
77
  rubocop (~> 1.0)
80
- rubocop-ast (>= 1.1.0)
78
+ rubocop-rspec (2.6.0)
79
+ rubocop (~> 1.19)
81
80
  ruby-progressbar (1.11.0)
82
81
  simplecov (0.21.2)
83
82
  docile (~> 1.1)
84
83
  simplecov-html (~> 0.11)
85
84
  simplecov_json_formatter (~> 0.1)
86
85
  simplecov-html (0.12.3)
87
- simplecov_json_formatter (0.1.2)
86
+ simplecov_json_formatter (0.1.3)
88
87
  smart_engine (0.11.0)
89
- smart_types (0.4.0)
88
+ smart_types (0.7.0)
90
89
  smart_engine (~> 0.11)
91
90
  tzinfo (2.0.4)
92
91
  concurrent-ruby (~> 1.0)
93
- unicode-display_width (2.0.0)
94
- zeitwerk (2.4.2)
92
+ unicode-display_width (2.1.0)
93
+ zeitwerk (2.5.1)
95
94
 
96
95
  PLATFORMS
97
96
  x86_64-darwin-19
98
97
  x86_64-darwin-20
98
+ x86_64-darwin-21
99
99
 
100
100
  DEPENDENCIES
101
- armitage-rubocop (~> 1.7)
101
+ armitage-rubocop (~> 1.23)
102
102
  bundler (~> 2.2)
103
103
  pry (~> 0.14)
104
104
  rake (~> 13.0)
@@ -107,4 +107,4 @@ DEPENDENCIES
107
107
  smart_initializer!
108
108
 
109
109
  BUNDLED WITH
110
- 2.2.19
110
+ 2.2.31
data/README.md CHANGED
@@ -1,8 +1,14 @@
1
- # SmartCore::Initializer &middot; [![Gem Version](https://badge.fury.io/rb/smart_initializer.svg)](https://badge.fury.io/rb/smart_initializer)
1
+ # SmartCore::Initializer &middot; <a target="_blank" href="https://github.com/Cado-Labs"><img src="https://github.com/Cado-Labs/cado-labs-logos/raw/main/cado_labs_badge.svg" alt="Supported by Cado Labs" style="max-width: 100%; height: 20px"></a> &middot; [![Gem Version](https://badge.fury.io/rb/smart_initializer.svg)](https://badge.fury.io/rb/smart_initializer)
2
2
 
3
3
  A simple and convenient way to declare complex constructors with a support for various commonly used type systems.
4
4
  (**in active development**).
5
5
 
6
+ ---
7
+
8
+ <img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
9
+
10
+ ---
11
+
6
12
  ## Installation
7
13
 
8
14
  ```ruby
@@ -24,9 +30,21 @@ require 'smart_core/initializer'
24
30
  ## Table of contents
25
31
 
26
32
  - [Synopsis](#synopsis)
33
+ - [Initialization flow](#initialization-flow)
34
+ - [Attribute value definition flow](#attribute-value-definition-flow-during-object-allocation-and-construction)
35
+ - [Constructor definition](#constructor-definition)
36
+ - [param](#param)
37
+ - [option](#option)
38
+ - [params](#params)
39
+ - [options](#options)
40
+ - [param and params signature](#param-and-params-signature)
41
+ - [option and options signature](#option-and-options-signature)
42
+ - [Initializer integration](#initializer-integration)
43
+ - [Basic Example](#basic-example)
27
44
  - [Access to the instance attributes](#access-to-the-instance-attributes)
28
45
  - [Configuration](#configuration)
29
46
  - [Type aliasing](#type-aliasing)
47
+ - [Type auto-casting](#type-auto-casting)
30
48
  - [Initialization extension](#initialization-extension)
31
49
  - [Plugins](#plugins)
32
50
  - [thy-types](#plugin-thy-types)
@@ -37,51 +55,69 @@ require 'smart_core/initializer'
37
55
 
38
56
  ## Synopsis
39
57
 
40
- **Initialization flow**:
58
+ #### Initialization flow
41
59
 
42
- 1. Parameter + Option definitioning;
43
- 2. Original #initialize invokation;
60
+ 1. Parameter + Option definitioning and initialization;
61
+ 2. Original **#initialize** invokation;
44
62
  3. Initialization extensions invokation;
45
63
 
46
- **Constructor definition**:
64
+ **NOTE!**: original constructor is called after **SmarteCore::Initializer**'s constructor
65
+ in order to guarantee the validity of the SmartCore::Initializer's functionality
66
+ (such as `attribute overlap chek`, `instant type checking`, `value post-processing by finalize`, etc)
67
+
68
+ #### Attribute value definition flow (during object allocation and construction):
69
+
70
+ 1. `original value`
71
+ 2. *(if defined)*: `default value` (default value is used when `original value` is not defined)
72
+ 3. *(if defined)*: `finalize`;
73
+
74
+ ---
75
+
76
+ ### Constructor definition DSL
77
+
78
+ **NOTE**: last `Hash` argument will be treated as `kwarg`s;
79
+
80
+ #### param
47
81
 
48
82
  - `param` - defines name-like attribute:
49
- - `cast` - type-cast received value if value has invalid type;
50
- - `privacy` - reader incapsulation level;
51
- - `finalize` - value post-processing (receives method name or proc);
52
- - `type_system` - differently chosen type system for the current attribute;
53
- - (limitation) param has no `:default` option;
54
- - `option` - defined kwarg-like attribute:
55
- - `cast` - type-cast received value if value has invalid type;
56
- - `privacy` - reader incapsulation level;
57
- - `finalize` - value post-processing (receives method name or proc);
58
- - `default` - defalut value (if an attribute is not provided);
59
- - `type_system` - differently chosen type system for the current attribute;
60
- - last `Hash` argument will be treated as `kwarg`s;
83
+ - `cast` (optional) - type-cast received value if value has invalid type;
84
+ - `privacy` (optional) - reader incapsulation level;
85
+ - `finalize` (optional) - value post-processing (receives method name or proc) (the result value type is also validate);
86
+ - `type_system` (optional) - differently chosen type system for the current attribute;
87
+ - `as` (optional)- attribute alias (be careful with naming aliases that overlap the names of other attributes);
88
+ - `mutable` (optional) - generate type-validated attr_writer in addition to attr_reader (`false` by default)
89
+ - (**limitation**) param has no `:default` option;
61
90
 
62
- #### initializer integration
91
+ #### option
63
92
 
64
- ```ruby
65
- # with pre-configured type system (:smart_types, see Configuration doc)
93
+ - `option` - defined kwarg-like attribute:
94
+ - `cast` (optional) - type-cast received value if value has invalid type;
95
+ - `privacy` (optional) - reader incapsulation level;
96
+ - `as` (optional) - attribute alias (be careful with naming aliases that overlap the names of other attributes);
97
+ - `mutable` (optional) - generate type-validated attr_writer in addition to attr_reader (`false` by default)
98
+ - `optional` (optional) - mark attribut as optional (you can may not initialize optional attributes,
99
+ their values will be initialized with `nil` or by `default:` parameter);
100
+ - `finalize` (optional) - value post-processing (receives method name or proc) (the result value type is also validate);
101
+ - expects `Proc` object or `symbol`/`string` isntance method;
102
+ - `default` (optional) - defalut value (if an attribute is not provided);
103
+ - expects `Proc` object or a simple value of any type;
104
+ - non-proc values will be `dup`licate during initialization;
105
+ - `type_system` (optional) - differently chosen type system for the current attribute;
66
106
 
67
- class MyStructure
68
- include SmartCore::Initializer
69
- end
70
- ```
107
+ #### params
71
108
 
72
- ```ruby
73
- # with manually chosen type system
109
+ - `params` - define a series of parameters;
110
+ - `:mutable` (optional) - (`false` by default);
111
+ - `:privacy` (optional) - (`:public` by default);
74
112
 
75
- class MyStructure
76
- include SmartCore::Initializer(type_system: :smart_types)
77
- end
113
+ #### options
78
114
 
79
- class AnotherStructure
80
- include SmartCore::Initializer(type_system: :thy_types)
81
- end
82
- ```
115
+ - `options` - define a series of options;
116
+ - `:mutable` (optional) - (`false` by default);
117
+ - `:privacy` (optional) - (`:public` by default);
83
118
 
84
- #### `param` signautre:
119
+
120
+ #### `param` and `params` signautre:
85
121
 
86
122
  ```ruby
87
123
  param <attribute_name>,
@@ -89,10 +125,19 @@ param <attribute_name>,
89
125
  cast: false, # false by default
90
126
  privacy: :public, # :public by default
91
127
  finalize: proc { |value| value }, # no finalization by default
128
+ finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
129
+ as: :some_alias, # define attribute alias
130
+ mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
92
131
  type_system: :smart_types # used by default
93
132
  ```
94
133
 
95
- #### `option` signature:
134
+ ```ruby
135
+ params <atribute_name1>, <attribute_name2>, <attribute_name3>, ...,
136
+ mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
137
+ privacy: :private # incapsulate all attributes as private
138
+ ```
139
+
140
+ #### `option` and `options` signature:
96
141
 
97
142
  ```ruby
98
143
  option <attribute_name>,
@@ -100,11 +145,58 @@ option <attribute_name>,
100
145
  cast: false, # false by default
101
146
  privacy: :public, # :public by default
102
147
  finalize: proc { |value| value }, # no finalization by default
148
+ finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
103
149
  default: 123, # no default value by default
150
+ default: proc { 123 }, # use proc/lambda object for dynamic initialization
151
+ as: :some_alias, # define attribute alias
152
+ mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
153
+ optional: true # (false by default) mark attribute as optional (attribute will be defined with `nil` or by `default:` value)
104
154
  type_system: :smart_types # used by default
105
155
  ```
106
156
 
107
- Example:
157
+ ```ruby
158
+ options <attribute_name1>, <attribute_name2>, <attribute_name3>, ...,
159
+ mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
160
+ privacy: :private # incapsulate all attributes as private
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Initializer integration
166
+
167
+ - supports per-class configurations;
168
+ - possible configurations:
169
+ - `:type_system` - chosen type-system (`smart_types` by default);
170
+ - `:strict_options` - fail extra kwarg-attributes, passed to the constructor (`true` by default);
171
+ - `:auto_cast` - type-cast all values to the declared attribute type (`false` by default);
172
+
173
+ ```ruby
174
+ # with pre-configured type system (:smart_types, see Configuration doc)
175
+
176
+ class MyStructure
177
+ include SmartCore::Initializer
178
+ end
179
+ ```
180
+
181
+ ```ruby
182
+ # with manually chosen settings
183
+
184
+ class MyStructure
185
+ include SmartCore::Initializer(
186
+ type_system: :smart_types, # use smart_types
187
+ auto_cast: true, # type-cast all values by default
188
+ strict_options: false # ignore extra kwargs passed to the constructor
189
+ )
190
+ end
191
+
192
+ class AnotherStructure
193
+ include SmartCore::Initializer(type_system: :thy_types) # use thy_types and global defaults
194
+ end
195
+ ```
196
+
197
+ ---
198
+
199
+ ### Basic Example:
108
200
 
109
201
 
110
202
  ```ruby
@@ -114,13 +206,34 @@ class User
114
206
  include SmartCore::Initializer(type_system: :smart_types)
115
207
 
116
208
  param :user_id, SmartCore::Types::Value::Integer, cast: false, privacy: :public
209
+ param :login, :string, mutable: true
210
+
117
211
  option :role, default: :user, finalize: -> { |value| Role.find(name: value) }
118
212
 
213
+ # NOTE: for method-based finalizetion use `your_method(value)` isntance method of your class;
214
+ # NOTE: for dynamic default values use `proc` objects and `lambda` objects;
215
+
119
216
  params :name, :password
120
217
  options :metadata, :enabled
121
218
  end
122
219
 
123
- User.new(1, 'John', 'test123', role: :admin, metadata: {}, enabled: false)
220
+ # with correct types (incorrect types will raise SmartCore::Initializer::IncorrectTypeError)
221
+ object = User.new(1, 'kek123', 'John', 'test123', role: :admin, metadata: {}, enabled: false)
222
+
223
+ # attribute accessing:
224
+ object.user_id # => 1
225
+ object.login # => 'kek123'
226
+ object.name # => 'John'
227
+ object.password # => 'test123'
228
+ object.role # => :admin
229
+ object.metadata # => {}
230
+ object.enabled # => false
231
+
232
+ # attribute mutation (only mutable attributes have a mutator):
233
+ object.login = 123 # => (type vlaidation error) raises SmartCore::Initializer::IncorrectTypeError (expected String, got Integer)
234
+ object.login # => 'kek123'
235
+ object.login = 'pek456'
236
+ object.login # => 'pek456'
124
237
  ```
125
238
 
126
239
  ---
@@ -152,27 +265,65 @@ user.__attributes__ # => { first_name: 'Rustam', second_name: 'Ibragimov', age:
152
265
 
153
266
  ## Configuration
154
267
 
155
- - based on `Qonfig` gem;
268
+ - **configuration setitngs**:
269
+ - `:default_type_system` - default type system (`smart_types` by default);
270
+ - `:strict_options` - fail on extra kwarg-attributes passed to the constructor (`true` by default);
271
+ - `:auto_cast` - type-cast all values to the declared attribute type (`false` by default);
272
+ - by default, all classes uses and inherits the Global configuration;
156
273
  - you can read config values via `[]` or `.config.settings` or `.config[key]`;
157
- - setitngs:
158
- - `default_type_system` - default type system (`smart_types` by default);
159
- - `strict_options` - raise an error when got unknown options if true (`true` by default);
274
+ - each class can be configured separately (in `include` invocation);
275
+ - global configuration affects classes used the default global configs in run-time;
276
+ - each class can be re-configured separately in run-time;
277
+ - based on `Qonfig` gem;
160
278
 
161
279
  ```ruby
162
- # configure:
280
+ # Global configuration:
281
+
163
282
  SmartCore::Initializer::Configuration.configure do |config|
164
283
  config.default_type_system = :smart_types # default setting value
165
284
  config.strict_options = true # default setting value
285
+ config.auto_cast = false # default setting value
166
286
  end
167
287
  ```
168
288
 
169
289
  ```ruby
170
- # read:
290
+ # Read configs:
291
+
171
292
  SmartCore::Initializer::Configuration[:default_type_system]
172
293
  SmartCore::Initializer::Configuration.config[:default_type_system]
173
294
  SmartCore::Initializer::Configuration.config.settings.default_type_system
174
295
  ```
175
296
 
297
+ ```ruby
298
+ # per-class configuration:
299
+
300
+ class Parameters
301
+ include SmartCore::Initializer(auto_cast: true, strict_options: false)
302
+ # 1. use globally configured `smart_types` (default value)
303
+ # 2. type-cast all attributes by default (auto_cast: true)
304
+ # 3. ignore extra kwarg-attributes passed to the constructor (strict_options: false)
305
+ end
306
+
307
+ class User
308
+ include SmartCore::Initializer(type_system: :thy_types)
309
+ # 1. use :thy_types isntead of pre-configured :smart_types
310
+ # 2. use pre-configured auto_cast (false by default above)
311
+ # 3. use pre-configured strict_options ()
312
+ end
313
+ ```
314
+
315
+ ```ruby
316
+ # debug class-related configurations:
317
+
318
+ class SomeClass
319
+ include SmartCore::Initializer(type_system: :thy_types)
320
+ end
321
+
322
+ SomeClass.__initializer_settings__[:type_system] # => :thy_types
323
+ SomeClass.__initializer_settings__[:auto_cast] # => false
324
+ SomeClass.__initializer_settings__[:strict_options] # => true
325
+ ```
326
+
176
327
  ---
177
328
 
178
329
  ## Type aliasing
@@ -208,6 +359,63 @@ SmartCore::Initializer::TypeSystem::ThyTypes.type_aliases
208
359
 
209
360
  ---
210
361
 
362
+ ## Type-casting
363
+
364
+ - make param/option as type-castable:
365
+
366
+ ```ruby
367
+ class Order
368
+ include SmartCore::Initializer
369
+
370
+ param :manager, 'string' # cast: false is used by default
371
+ param :amount, 'float', cast: true
372
+
373
+ option :status, :symbol # cast: false is used by default
374
+ option :is_processed, 'boolean', cast: true
375
+ option :processed_at, 'time', cast: true
376
+ end
377
+
378
+ order = Order.new(
379
+ 'Daiver',
380
+ '123.456',
381
+ status: :pending,
382
+ is_processed: nil,
383
+ processed_at: '2021-01-01'
384
+ )
385
+
386
+ order.manager # => 'Daiver'
387
+ order.amount # => 123.456 (type casted)
388
+ order.status # => :pending
389
+ order.is_processed # => false (type casted)
390
+ order.processed_at # => 2021-01-01 00:00:00 +0300 (type casted)
391
+ ```
392
+
393
+ - configure automatic type casting:
394
+
395
+ ```ruby
396
+ # per class
397
+
398
+ class User
399
+ include SmartCore::Initializer(auto_cast: true) # auto type cast every attribute
400
+
401
+ param :x, 'string'
402
+ param :y, 'numeric', cast: false # disable type-casting
403
+
404
+ option :b, 'integer', cast: false # disable type-casting
405
+ option :c, 'boolean'
406
+ end
407
+ ```
408
+
409
+ ```ruby
410
+ # globally
411
+
412
+ SmartCore::Initializer::Configuration.configure do |config|
413
+ config.auto_cast = true # false by default
414
+ end
415
+ ```
416
+
417
+ ---
418
+
211
419
  ## Initialization extension
212
420
 
213
421
  - `ext_init(&block)`:
@@ -291,9 +499,9 @@ User.new(123, 'test', { admin: true, age: 22 })
291
499
 
292
500
  ## Roadmap
293
501
 
294
- - (in development) Attribue Definition DSL
295
- - Support for specifying the attribute accessor type (`read_only` parameter);
296
- - Support for attribute aliasing (`as` parameter);
502
+ - (**thinking** / **discussing**) Finalize should be invoked on `mutable` attributes after mutation too;
503
+ - Support for `RSpec` doubles and instance_doubles inside the type system integration;
504
+ - Specs restructuring;
297
505
  - Migrate from `TravisCI` to `GitHub Actions`;
298
506
  - Extract `Type Interop` system to `smart_type-system`;
299
507
 
@@ -349,6 +557,12 @@ bundle exec rake rubocop -A
349
557
 
350
558
  Released under MIT License.
351
559
 
560
+ ## Supporting
561
+
562
+ <a target="_blank" href="https://github.com/Cado-Labs">
563
+ <img src="https://github.com/Cado-Labs/cado-labs-logos/raw/main/cado_labs_badge.svg" alt="Supported by Cado Labs" style="max-width: 100%;">
564
+ </a>
565
+
352
566
  ## Authors
353
567
 
354
568
  [Rustam Ibragimov](https://github.com/0exp)
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'bundler/setup'
5
- require 'smart_core'
6
-
5
+ require 'smart_core/initializer'
7
6
  require 'pry'
7
+
8
8
  Pry.start