smart_initializer 0.7.0 → 0.8.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 (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