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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +35 -3
- data/Gemfile.lock +38 -38
- data/README.md +260 -46
- data/bin/console +2 -2
- data/gemfiles/with_external_deps.gemfile.lock +38 -38
- data/lib/smart_core/initializer/attribute/factory/base.rb +145 -0
- data/lib/smart_core/initializer/attribute/factory/option.rb +107 -0
- data/lib/smart_core/initializer/attribute/factory/param.rb +63 -0
- data/lib/smart_core/initializer/attribute/factory.rb +5 -199
- data/lib/smart_core/initializer/attribute/finalizer/abstract.rb +2 -0
- data/lib/smart_core/initializer/attribute/finalizer/instance_method.rb +1 -1
- data/lib/smart_core/initializer/attribute/finalizer.rb +5 -5
- data/lib/smart_core/initializer/attribute/list.rb +20 -0
- data/lib/smart_core/initializer/attribute/{parameters.rb → value/base.rb} +35 -65
- data/lib/smart_core/initializer/attribute/value/option.rb +101 -0
- data/lib/smart_core/initializer/attribute/value/param.rb +24 -0
- data/lib/smart_core/initializer/attribute/value.rb +9 -0
- data/lib/smart_core/initializer/attribute.rb +3 -125
- data/lib/smart_core/initializer/configuration.rb +7 -3
- data/lib/smart_core/initializer/constructor/definer.rb +135 -46
- data/lib/smart_core/initializer/constructor.rb +30 -12
- data/lib/smart_core/initializer/dsl.rb +38 -24
- data/lib/smart_core/initializer/errors.rb +20 -4
- data/lib/smart_core/initializer/functionality.rb +7 -8
- data/lib/smart_core/initializer/settings/auto_cast.rb +40 -0
- data/lib/smart_core/initializer/settings/base.rb +49 -0
- data/lib/smart_core/initializer/settings/duplicator.rb +5 -0
- data/lib/smart_core/initializer/settings/strict_options.rb +40 -0
- data/lib/smart_core/initializer/settings/type_system.rb +10 -28
- data/lib/smart_core/initializer/settings.rb +40 -0
- data/lib/smart_core/initializer/type_system/registry.rb +2 -1
- data/lib/smart_core/initializer/type_system/smart_types.rb +2 -2
- data/lib/smart_core/initializer/version.rb +2 -2
- data/lib/smart_core/initializer.rb +14 -4
- data/smart_initializer.gemspec +2 -2
- metadata +16 -7
@@ -14,6 +14,7 @@ module SmartCore::Initializer::Attribute::Finalizer
|
|
14
14
|
#
|
15
15
|
# @api private
|
16
16
|
# @since 0.1.0
|
17
|
+
# @version 0.8.0
|
17
18
|
def create(finalization_approach)
|
18
19
|
case finalization_approach
|
19
20
|
when String, Symbol
|
@@ -21,11 +22,10 @@ module SmartCore::Initializer::Attribute::Finalizer
|
|
21
22
|
when Proc
|
22
23
|
AnonymousBlock.new(finalization_approach)
|
23
24
|
else
|
24
|
-
|
25
|
-
|
26
|
-
Finalization approach should be a type of Proc, Symbol or String'
|
27
|
-
|
28
|
-
# :nocov:
|
25
|
+
raise(
|
26
|
+
SmartCore::Initializer::ArgumentError,
|
27
|
+
'Finalization approach object should be a type of Proc, Symbol or String'
|
28
|
+
)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -15,6 +15,26 @@ class SmartCore::Initializer::Attribute::List
|
|
15
15
|
@lock = SmartCore::Engine::Lock.new
|
16
16
|
end
|
17
17
|
|
18
|
+
# @param attribute_name [Symbol]
|
19
|
+
# @return [SmartCore::Initializer::Atribute]
|
20
|
+
#
|
21
|
+
# @raise [SmartCore::Initializer::UndefinedAttributeError]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
# @since 0.8.0
|
25
|
+
def fetch(attribute_name)
|
26
|
+
thread_safe do
|
27
|
+
attributes.fetch(attribute_name)
|
28
|
+
rescue ::KeyError
|
29
|
+
raise(
|
30
|
+
::SmartCore::Initializer::UndefinedAttributeError,
|
31
|
+
"Attribute with `#{attribute_name}` name is not defined in your constructor. " \
|
32
|
+
"Please, check your attribute definitions inside your class."
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias_method :[], :fetch
|
37
|
+
|
18
38
|
# @param attribute [SmartCore::Initializer::Attribute]
|
19
39
|
# @return [void]
|
20
40
|
#
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# @api private
|
4
|
-
# @since 0.
|
5
|
-
class SmartCore::Initializer::Attribute::
|
4
|
+
# @since 0.8.0
|
5
|
+
class SmartCore::Initializer::Attribute::Value::Base
|
6
6
|
# @return [Hash<Symbol,Symbol>]
|
7
7
|
#
|
8
8
|
# @api private
|
9
|
-
# @since 0.
|
9
|
+
# @since 0.8.0
|
10
10
|
PRIVACY_MODES = {
|
11
11
|
public: :public,
|
12
12
|
protected: :protected,
|
@@ -16,93 +16,76 @@ class SmartCore::Initializer::Attribute::Parameters
|
|
16
16
|
# @return [Symbol]
|
17
17
|
#
|
18
18
|
# @api private
|
19
|
-
# @since 0.
|
19
|
+
# @since 0.8.0
|
20
20
|
DEFAULT_PRIVACY_MODE = PRIVACY_MODES[:public]
|
21
21
|
|
22
|
-
# @return [Boolean]
|
23
|
-
#
|
24
|
-
# @api private
|
25
|
-
# @since 0.1.0
|
26
|
-
DEFAULT_CAST_BEHAVIOUR = false
|
27
|
-
|
28
22
|
# @return [Proc]
|
29
23
|
#
|
30
24
|
# @api private
|
31
|
-
# @since 0.
|
25
|
+
# @since 0.8.0
|
32
26
|
DEFAULT_FINALIZER = proc { |value| value }.freeze
|
33
27
|
|
34
|
-
# @return [
|
28
|
+
# @return [NilClass]
|
35
29
|
#
|
36
30
|
# @api private
|
37
|
-
# @since 0.
|
38
|
-
|
31
|
+
# @since 0.8.0
|
32
|
+
DEFAULT_AS = nil
|
39
33
|
|
40
34
|
# @return [Boolean]
|
41
35
|
#
|
42
36
|
# @api private
|
43
|
-
# @since 0.
|
44
|
-
|
45
|
-
|
46
|
-
# @return [NilClass]
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
# @since 0.4.0
|
50
|
-
DEFAULT_AS = nil
|
37
|
+
# @since 0.8.0
|
38
|
+
DEFAULT_MUTABLE = false
|
51
39
|
|
52
40
|
# @return [Symbol]
|
53
41
|
#
|
54
42
|
# @api private
|
55
|
-
# @since 0.
|
43
|
+
# @since 0.8.0
|
56
44
|
attr_reader :name
|
57
45
|
|
58
46
|
# @return [SmartCore::Initializer::TypeSystem::Interop]
|
59
47
|
#
|
60
48
|
# @api private
|
61
|
-
# @since 0.
|
49
|
+
# @since 0.8.0
|
62
50
|
attr_reader :type
|
63
51
|
|
64
52
|
# @return [Class<SmartCore::Initilizer::TypeSystem::Interop>]
|
65
53
|
#
|
66
54
|
# @api private
|
67
|
-
# @since 0.
|
55
|
+
# @since 0.8.0
|
68
56
|
attr_reader :type_system
|
69
57
|
|
70
58
|
# @return [Symbol]
|
71
59
|
#
|
72
60
|
# @api private
|
73
|
-
# @since 0.
|
61
|
+
# @since 0.8.0
|
74
62
|
attr_reader :privacy
|
75
63
|
|
76
64
|
# @return [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock]
|
77
65
|
# @return [SmartCore::Initializer::Attribute::Finalizer::InstanceMethod]
|
78
66
|
#
|
79
67
|
# @api private
|
80
|
-
# @since 0.
|
68
|
+
# @since 0.8.0
|
81
69
|
attr_reader :finalizer
|
82
70
|
|
83
71
|
# @return [Boolean]
|
84
72
|
#
|
85
73
|
# @api private
|
86
|
-
# @since 0.
|
74
|
+
# @since 0.8.0
|
87
75
|
attr_reader :cast
|
88
76
|
alias_method :cast?, :cast
|
89
77
|
|
90
|
-
# @return [Hash<Symbol,Any>]
|
91
|
-
#
|
92
|
-
# @api private
|
93
|
-
# @since 0.1.0
|
94
|
-
attr_reader :dynamic_options
|
95
|
-
|
96
78
|
# @return [Boolean]
|
97
79
|
#
|
98
80
|
# @api private
|
99
|
-
# @since 0.
|
100
|
-
attr_reader :
|
81
|
+
# @since 0.8.0
|
82
|
+
attr_reader :mutable
|
83
|
+
alias_method :mutable?, :mutable
|
101
84
|
|
102
85
|
# @return [String, Symbol, NilClass]
|
103
86
|
#
|
104
87
|
# @api private
|
105
|
-
# @since 0.
|
88
|
+
# @since 0.8.0
|
106
89
|
attr_reader :as
|
107
90
|
|
108
91
|
# @param name [Symbol]
|
@@ -111,48 +94,35 @@ class SmartCore::Initializer::Attribute::Parameters
|
|
111
94
|
# @param privacy [Symbol]
|
112
95
|
# @param finalizer [SmartCore::Initializer::Attribute::AnonymousBlock/InstanceMethod]
|
113
96
|
# @param cast [Boolean]
|
114
|
-
# @param
|
97
|
+
# @param mutable [Boolean]
|
115
98
|
# @param as [NilClass, Symbol, String]
|
116
|
-
# @param dynamic_options [Hash<Symbol,Any>]
|
117
|
-
# - :default - default value (Proc value will be called)
|
118
99
|
# @return [void]
|
119
100
|
#
|
120
101
|
# @api private
|
121
|
-
# @since 0.
|
122
|
-
|
123
|
-
def initialize(name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options)
|
102
|
+
# @since 0.8.0
|
103
|
+
def initialize(name, type, type_system, privacy, finalizer, cast, mutable, as)
|
124
104
|
@name = name
|
125
105
|
@type = type
|
126
106
|
@type_system = type_system
|
127
107
|
@privacy = privacy
|
128
108
|
@finalizer = finalizer
|
129
109
|
@cast = cast
|
130
|
-
@
|
110
|
+
@mutable = mutable
|
131
111
|
@as = as
|
132
|
-
@dynamic_options = dynamic_options
|
133
112
|
end
|
134
113
|
|
135
|
-
# @
|
136
|
-
#
|
137
|
-
# @api private
|
138
|
-
# @since 0.1.0
|
139
|
-
def has_default?
|
140
|
-
dynamic_options.key?(:default)
|
141
|
-
end
|
142
|
-
|
143
|
-
# @return [Any]
|
144
|
-
#
|
145
|
-
# @raise [SmartCore::Initializer::NoDefaultValueError]
|
114
|
+
# @param value [Any]
|
115
|
+
# @return [void]
|
146
116
|
#
|
147
117
|
# @api private
|
148
|
-
# @since 0.
|
149
|
-
def
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
118
|
+
# @since 0.8.0
|
119
|
+
def validate!(value)
|
120
|
+
type.validate!(value)
|
121
|
+
rescue => error # TODO: move to typesystem interop
|
122
|
+
raise(
|
123
|
+
SmartCore::Initializer::IncorrectTypeError,
|
124
|
+
"Validation of attribute `#{name}` failed:" \
|
125
|
+
"(expected: #{type.identifier}, got: #{value.class}) \"#{error.message}\""
|
126
|
+
)
|
157
127
|
end
|
158
128
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::Attribute::Value
|
4
|
+
# @api private
|
5
|
+
# @since 0.8.0
|
6
|
+
class Option < Base
|
7
|
+
# @return [Object]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.8.0
|
11
|
+
UNDEFINED_DEFAULT = ::Object.new.tap(&:freeze)
|
12
|
+
|
13
|
+
# @return [Boolean]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
# @since 0.8.0
|
17
|
+
DEFAULT_OPTIONAL = false
|
18
|
+
|
19
|
+
# @return [Boolean]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.8.0
|
23
|
+
attr_reader :optional
|
24
|
+
alias_method :optional?, :optional
|
25
|
+
|
26
|
+
# @param name [Symbol]
|
27
|
+
# @param type [SmartCore::Initializer::TypeSystem::Interop]
|
28
|
+
# @param type_system [Class<SmartCore::Initializer::TypeSystem::Interop>]
|
29
|
+
# @param privacy [Symbol]
|
30
|
+
# @param finalizer [SmartCore::Initializer::Attribute::AnonymousBlock/InstanceMethod]
|
31
|
+
# @param cast [Boolean]
|
32
|
+
# @param mutable [Boolean]
|
33
|
+
# @param as [NilClass, Symbol, String]
|
34
|
+
# @param default [Proc, Any]
|
35
|
+
# @param optional [Boolean]
|
36
|
+
# @return [void]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.8.0
|
40
|
+
def initialize(
|
41
|
+
name,
|
42
|
+
type,
|
43
|
+
type_system,
|
44
|
+
privacy,
|
45
|
+
finalizer,
|
46
|
+
cast,
|
47
|
+
mutable,
|
48
|
+
as,
|
49
|
+
default,
|
50
|
+
optional
|
51
|
+
)
|
52
|
+
super(name, type, type_system, privacy, finalizer, cast, mutable, as)
|
53
|
+
@default = default
|
54
|
+
@optional = optional
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Boolean]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
# @since 0.8.0
|
61
|
+
def has_default?
|
62
|
+
!@default.equal?(UNDEFINED_DEFAULT)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Any]
|
66
|
+
#
|
67
|
+
# @raise [SmartCore::Initializer::NoDefaultValueError]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
# @since 0.8.0
|
71
|
+
def default
|
72
|
+
raise(
|
73
|
+
SmartCore::Initializer::NoDefaultValueError,
|
74
|
+
"Attribute #{name} has no default value"
|
75
|
+
) if @default.equal?(UNDEFINED_DEFAULT)
|
76
|
+
|
77
|
+
@default.is_a?(Proc) ? @default.call : @default.dup
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [SmartCore::Initializer::Attribute::Value::Option]
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
# @since 0.8.0
|
84
|
+
def dup
|
85
|
+
default = @default.equal?(UNDEFINED_DEFAULT) ? @default : @default.dup
|
86
|
+
|
87
|
+
self.class.new(
|
88
|
+
name.dup,
|
89
|
+
type,
|
90
|
+
type_system,
|
91
|
+
privacy,
|
92
|
+
finalizer.dup,
|
93
|
+
cast,
|
94
|
+
mutable,
|
95
|
+
as,
|
96
|
+
default,
|
97
|
+
optional
|
98
|
+
)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Initializer::Attribute::Value
|
4
|
+
# @api private
|
5
|
+
# @since 0.8.0
|
6
|
+
class Param < Base
|
7
|
+
# @return [SmartCore::Initializer::Attribute::Value::Param]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.8.0
|
11
|
+
def dup
|
12
|
+
self.class.new(
|
13
|
+
name.dup,
|
14
|
+
type,
|
15
|
+
type_system,
|
16
|
+
privacy,
|
17
|
+
finalizer.dup,
|
18
|
+
cast,
|
19
|
+
mutable,
|
20
|
+
as
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,132 +2,10 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
|
-
|
6
|
-
|
5
|
+
# @version 0.8.0
|
6
|
+
module SmartCore::Initializer::Attribute
|
7
|
+
require_relative 'attribute/value'
|
7
8
|
require_relative 'attribute/list'
|
8
9
|
require_relative 'attribute/finalizer'
|
9
10
|
require_relative 'attribute/factory'
|
10
|
-
|
11
|
-
# @since 0.1.0
|
12
|
-
extend ::Forwardable
|
13
|
-
|
14
|
-
# @return [Symbol]
|
15
|
-
#
|
16
|
-
# @pai private
|
17
|
-
# @since 0.1.0
|
18
|
-
def_delegator :parameters, :name
|
19
|
-
|
20
|
-
# @return [SmartCore::Initializer::TypeSystem::Interop]
|
21
|
-
#
|
22
|
-
# @pai private
|
23
|
-
# @since 0.1.0
|
24
|
-
def_delegator :parameters, :type
|
25
|
-
|
26
|
-
# @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
# @since 0.1.0
|
30
|
-
def_delegator :parameters, :type_system
|
31
|
-
|
32
|
-
# @return [Symbol]
|
33
|
-
#
|
34
|
-
# @pai private
|
35
|
-
# @since 0.1.0
|
36
|
-
def_delegator :parameters, :privacy
|
37
|
-
|
38
|
-
# @return [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock/InstanceMethod]
|
39
|
-
#
|
40
|
-
# @pai private
|
41
|
-
# @since 0.1.0
|
42
|
-
def_delegator :parameters, :finalizer
|
43
|
-
|
44
|
-
# @return [Boolean]
|
45
|
-
#
|
46
|
-
# @pai private
|
47
|
-
# @since 0.1.0
|
48
|
-
def_delegators :parameters, :cast, :cast?
|
49
|
-
|
50
|
-
# @return [Any]
|
51
|
-
#
|
52
|
-
# @api private
|
53
|
-
# @since 0.1.0
|
54
|
-
def_delegator :parameters, :default
|
55
|
-
|
56
|
-
# @return [Boolean]
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
# @since 0.1.0
|
60
|
-
def_delegator :parameters, :has_default?
|
61
|
-
|
62
|
-
# @return [Boolean]
|
63
|
-
#
|
64
|
-
# @api private
|
65
|
-
# @since 0.4.0
|
66
|
-
def_delegator :parameters, :read_only
|
67
|
-
|
68
|
-
# @return [String, Symbol, NilClass]
|
69
|
-
#
|
70
|
-
# @api private
|
71
|
-
# @since 0.4.0
|
72
|
-
def_delegator :parameters, :as
|
73
|
-
|
74
|
-
# @param name [Symbol]
|
75
|
-
# @param type [SmartCore::Initializer::TypeSystem::Interop]
|
76
|
-
# @param type_system [Class<SmartCore::Initializer::TypeSystem::Interop>]
|
77
|
-
# @param privacy [Symbol]
|
78
|
-
# @param finalizer [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock/InstanceMethod]
|
79
|
-
# @param cast [Boolean]
|
80
|
-
# @param read_only [Boolean]
|
81
|
-
# @param as [String, Symbol, NilClass]
|
82
|
-
# @param dynamic_options [Hash<Symbol,Any>]
|
83
|
-
# @return [void]
|
84
|
-
#
|
85
|
-
# @api private
|
86
|
-
# @since 0.1.0
|
87
|
-
def initialize(name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options)
|
88
|
-
@parameters = SmartCore::Initializer::Attribute::Parameters.new(
|
89
|
-
name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
# @param value [Any]
|
94
|
-
# @return [void]
|
95
|
-
#
|
96
|
-
# @api private
|
97
|
-
# @since 0.5.1
|
98
|
-
def validate!(value)
|
99
|
-
type.validate!(value)
|
100
|
-
rescue => error
|
101
|
-
raise SmartCore::Initializer::IncorrectTypeError,
|
102
|
-
"Validation of attribute '#{name}' (#{type.identifier}, got #{value.class}) failed: " \
|
103
|
-
"#{error.message}"
|
104
|
-
end
|
105
|
-
|
106
|
-
# @return [SmartCore::Initializer::Attribute]
|
107
|
-
#
|
108
|
-
# @api private
|
109
|
-
# @since 0.1.0
|
110
|
-
# rubocop:disable Metrics/AbcSize
|
111
|
-
def dup
|
112
|
-
self.class.new(
|
113
|
-
parameters.name.dup,
|
114
|
-
parameters.type,
|
115
|
-
parameters.type_system,
|
116
|
-
parameters.privacy,
|
117
|
-
parameters.finalizer.dup,
|
118
|
-
parameters.cast,
|
119
|
-
parameters.read_only,
|
120
|
-
parameters.as,
|
121
|
-
parameters.dynamic_options.dup
|
122
|
-
)
|
123
|
-
end
|
124
|
-
# rubocop:enable Metrics/AbcSize
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
# @return [SmartCore::Initializer::Attribute::Parameters]
|
129
|
-
#
|
130
|
-
# @api private
|
131
|
-
# @since 0.1.0
|
132
|
-
attr_reader :parameters
|
133
11
|
end
|
@@ -25,14 +25,18 @@ module SmartCore::Initializer::Configuration
|
|
25
25
|
|
26
26
|
# @since 0.1.0
|
27
27
|
configuration do
|
28
|
+
# @since 0.?.0
|
28
29
|
setting :default_type_system, :smart_types
|
29
30
|
validate :default_type_system do |value|
|
30
31
|
SmartCore::Initializer::TypeSystem.resolve(value) rescue false
|
31
32
|
end
|
32
33
|
|
34
|
+
# @since 0.?.0
|
33
35
|
setting :strict_options, true
|
34
|
-
validate :strict_options
|
35
|
-
|
36
|
-
|
36
|
+
validate :strict_options, :boolean
|
37
|
+
|
38
|
+
# @since 0.8.0
|
39
|
+
setting :auto_cast, false
|
40
|
+
validate :auto_cast, :boolean
|
37
41
|
end
|
38
42
|
end
|