dry-initializer 3.0.4 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/LICENSE +1 -1
- data/README.md +4 -3
- data/dry-initializer.gemspec +15 -13
- data/lib/dry/initializer/builders/attribute.rb +92 -82
- data/lib/dry/initializer/builders/initializer.rb +56 -54
- data/lib/dry/initializer/builders/reader.rb +55 -49
- data/lib/dry/initializer/builders/signature.rb +29 -23
- data/lib/dry/initializer/builders.rb +9 -5
- data/lib/dry/initializer/config.rb +160 -158
- data/lib/dry/initializer/definition.rb +58 -54
- data/lib/dry/initializer/dispatchers/build_nested_type.rb +54 -40
- data/lib/dry/initializer/dispatchers/check_type.rb +45 -39
- data/lib/dry/initializer/dispatchers/prepare_default.rb +32 -25
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +13 -6
- data/lib/dry/initializer/dispatchers/prepare_optional.rb +14 -7
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +29 -22
- data/lib/dry/initializer/dispatchers/prepare_source.rb +12 -5
- data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -37
- data/lib/dry/initializer/dispatchers/unwrap_type.rb +21 -10
- data/lib/dry/initializer/dispatchers/wrap_type.rb +24 -17
- data/lib/dry/initializer/dispatchers.rb +48 -43
- data/lib/dry/initializer/dsl.rb +42 -34
- data/lib/dry/initializer/errors.rb +22 -0
- data/lib/dry/initializer/mixin/local.rb +19 -13
- data/lib/dry/initializer/mixin/root.rb +12 -7
- data/lib/dry/initializer/mixin.rb +17 -12
- data/lib/dry/initializer/struct.rb +34 -29
- data/lib/dry/initializer/undefined.rb +7 -1
- data/lib/dry/initializer/version.rb +3 -1
- data/lib/dry/initializer.rb +12 -9
- data/lib/dry-initializer.rb +3 -1
- data/lib/tasks/benchmark.rake +15 -13
- data/lib/tasks/profile.rake +20 -16
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49644712268c1c8896eb7b9d067d5f3abf65789330d465f0acad780a4f50644e
|
4
|
+
data.tar.gz: 102ef164a75b9d4849400753a21046d5753217806de6c8963476ef8fafeb780d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '07780a5de808586056b92a3b9a2f1169f5fea4d7879abd1080fc27a7e6123b22d2a07878e9ca9203995c9f01c3e5a47b030b5dc7004d67a4a540413aabdb5890'
|
7
|
+
data.tar.gz: e352bf6de1a4aae2cf183be62ef4f64a4c70daf0f329122b0d6cd00a7e6081767aa745e938ae4464e52d322bfb08ce943a3312b4f92e02d87c1b968edf0498c4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
|
+
|
3
|
+
## 3.1.0 2022-01-16
|
4
|
+
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
|
8
|
+
- Improved error messages on type mismatch (@swerling)
|
9
|
+
- [BREAKING] Minimal supported Ruby version is 2.7 (@flash-gordon)
|
10
|
+
|
11
|
+
[Compare v3.0.4...v3.1.0](https://github.com/dry-rb/dry-initializer/compare/v3.0.4...v3.1.0)
|
12
|
+
|
1
13
|
## 3.0.4 2020-09-29
|
2
14
|
|
3
15
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
<!--- this file is synced from dry-rb/template-gem project -->
|
1
2
|
[gem]: https://rubygems.org/gems/dry-initializer
|
2
3
|
[actions]: https://github.com/dry-rb/dry-initializer/actions
|
3
4
|
[codacy]: https://www.codacy.com/gh/dry-rb/dry-initializer
|
@@ -14,15 +15,15 @@
|
|
14
15
|
|
15
16
|
## Links
|
16
17
|
|
17
|
-
* [User documentation](
|
18
|
+
* [User documentation](https://dry-rb.org/gems/dry-initializer)
|
18
19
|
* [API documentation](http://rubydoc.info/gems/dry-initializer)
|
19
20
|
|
20
21
|
## Supported Ruby versions
|
21
22
|
|
22
23
|
This library officially supports the following Ruby versions:
|
23
24
|
|
24
|
-
* MRI
|
25
|
-
* jruby
|
25
|
+
* MRI `>= 2.7.0`
|
26
|
+
* jruby `>= 9.3` (postponed until 2.7 is supported)
|
26
27
|
|
27
28
|
## License
|
28
29
|
|
data/dry-initializer.gemspec
CHANGED
@@ -1,33 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
# this file is managed by dry-rb/devtools project
|
3
2
|
|
4
|
-
|
3
|
+
# this file is synced from dry-rb/template-gem project
|
4
|
+
|
5
|
+
lib = File.expand_path("lib", __dir__)
|
5
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
-
require
|
7
|
+
require "dry/initializer/version"
|
7
8
|
|
8
9
|
Gem::Specification.new do |spec|
|
9
|
-
spec.name =
|
10
|
+
spec.name = "dry-initializer"
|
10
11
|
spec.authors = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
|
11
12
|
spec.email = ["andrew.kozin@gmail.com"]
|
12
|
-
spec.license =
|
13
|
+
spec.license = "MIT"
|
13
14
|
spec.version = Dry::Initializer::VERSION.dup
|
14
15
|
|
15
16
|
spec.summary = "DSL for declaring params and options of the initializer"
|
16
17
|
spec.description = spec.summary
|
17
|
-
spec.homepage =
|
18
|
+
spec.homepage = "https://dry-rb.org/gems/dry-initializer"
|
18
19
|
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-initializer.gemspec", "lib/**/*"]
|
19
|
-
spec.bindir =
|
20
|
+
spec.bindir = "bin"
|
20
21
|
spec.executables = []
|
21
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ["lib"]
|
22
23
|
|
23
|
-
spec.metadata[
|
24
|
-
spec.metadata[
|
25
|
-
spec.metadata[
|
26
|
-
spec.metadata[
|
24
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
25
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-initializer/blob/master/CHANGELOG.md"
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-initializer"
|
27
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-initializer/issues"
|
27
28
|
|
28
|
-
spec.required_ruby_version = ">= 2.
|
29
|
+
spec.required_ruby_version = ">= 2.7.0"
|
29
30
|
|
30
31
|
# to update dependencies edit project.yml
|
32
|
+
|
31
33
|
spec.add_development_dependency "rake"
|
32
34
|
spec.add_development_dependency "rspec"
|
33
35
|
end
|
@@ -1,86 +1,96 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Builders
|
6
|
+
# @private
|
7
|
+
class Attribute
|
8
|
+
def self.[](definition)
|
9
|
+
new(definition).call
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
lines.compact
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def initialize(definition)
|
19
|
+
@definition = definition
|
20
|
+
@option = definition.option
|
21
|
+
@type = definition.type
|
22
|
+
@optional = definition.optional
|
23
|
+
@default = definition.default
|
24
|
+
@source = definition.source
|
25
|
+
@ivar = definition.ivar
|
26
|
+
@null = definition.null ? "Dry::Initializer::UNDEFINED" : "nil"
|
27
|
+
@opts = "__dry_initializer_options__"
|
28
|
+
@congif = "__dry_initializer_config__"
|
29
|
+
@item = "__dry_initializer_definition__"
|
30
|
+
@val = @option ? "__dry_initializer_value__" : @source
|
31
|
+
end
|
32
|
+
|
33
|
+
def lines
|
34
|
+
[
|
35
|
+
"",
|
36
|
+
definition_line,
|
37
|
+
reader_line,
|
38
|
+
default_line,
|
39
|
+
coercion_line,
|
40
|
+
assignment_line
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
def reader_line
|
45
|
+
return unless @option
|
46
|
+
|
47
|
+
@optional ? optional_reader : required_reader
|
48
|
+
end
|
49
|
+
|
50
|
+
def optional_reader
|
51
|
+
"#{@val} = #{@opts}.fetch(:'#{@source}', #{@null})"
|
52
|
+
end
|
53
|
+
|
54
|
+
def required_reader
|
55
|
+
"#{@val} = #{@opts}.fetch(:'#{@source}')" \
|
56
|
+
" { raise KeyError, \"\#{self.class}: #{@definition} is required\" }"
|
57
|
+
end
|
58
|
+
|
59
|
+
def definition_line
|
60
|
+
return unless @type || @default
|
61
|
+
|
62
|
+
"#{@item} = __dry_initializer_config__.definitions[:'#{@source}']"
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_line
|
66
|
+
return unless @default
|
67
|
+
|
68
|
+
"#{@val} = instance_exec(&#{@item}.default) if #{@null} == #{@val}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def coercion_line
|
72
|
+
return unless @type
|
73
|
+
|
74
|
+
arity = @type.is_a?(Proc) ? @type.arity : @type.method(:call).arity
|
75
|
+
type_call_params = \
|
76
|
+
arity.equal?(1) || arity.negative? ? @val : "#{@val}, self"
|
77
|
+
|
78
|
+
<<-COERCE
|
79
|
+
begin
|
80
|
+
unless #{@null} == #{@val}
|
81
|
+
#{@val} = #{@item}.type.call(#{type_call_params})
|
82
|
+
end
|
83
|
+
rescue Dry::Types::ConstraintError => e
|
84
|
+
raise Dry::Initializer::CoercionError.new(e, '#{@source}')
|
85
|
+
end
|
86
|
+
COERCE
|
87
|
+
end
|
88
|
+
|
89
|
+
def assignment_line
|
90
|
+
"#{@ivar} = #{@val}" \
|
91
|
+
" unless #{@null} == #{@val} && instance_variable_defined?(:#{@ivar})"
|
92
|
+
end
|
78
93
|
end
|
79
94
|
end
|
80
|
-
|
81
|
-
def assignment_line
|
82
|
-
"#{@ivar} = #{@val}" \
|
83
|
-
" unless #{@null} == #{@val} && instance_variable_defined?(:#{@ivar})"
|
84
|
-
end
|
85
95
|
end
|
86
96
|
end
|
@@ -1,57 +1,59 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Builders
|
6
|
+
# @private
|
7
|
+
class Initializer
|
8
|
+
require_relative "signature"
|
9
|
+
require_relative "attribute"
|
10
|
+
|
11
|
+
def self.[](config)
|
12
|
+
new(config).call
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
lines.flatten.compact.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def initialize(config)
|
22
|
+
@config = config
|
23
|
+
@definitions = config.definitions.values
|
24
|
+
end
|
25
|
+
|
26
|
+
def lines
|
27
|
+
[
|
28
|
+
undef_line,
|
29
|
+
define_line,
|
30
|
+
params_lines,
|
31
|
+
options_lines,
|
32
|
+
end_line
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
def undef_line
|
37
|
+
"undef :__dry_initializer_initialize__" \
|
38
|
+
" if private_method_defined? :__dry_initializer_initialize__"
|
39
|
+
end
|
40
|
+
|
41
|
+
def define_line
|
42
|
+
"private def __dry_initializer_initialize__(#{Signature[@config]})"
|
43
|
+
end
|
44
|
+
|
45
|
+
def params_lines
|
46
|
+
@definitions.reject(&:option).flat_map { Attribute[_1] }.map { " #{_1}" }
|
47
|
+
end
|
48
|
+
|
49
|
+
def options_lines
|
50
|
+
@definitions.select(&:option).flat_map { Attribute[_1] }.map { " #{_1}" }
|
51
|
+
end
|
52
|
+
|
53
|
+
def end_line
|
54
|
+
"end"
|
55
|
+
end
|
56
|
+
end
|
55
57
|
end
|
56
58
|
end
|
57
59
|
end
|
@@ -1,52 +1,58 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Builders
|
6
|
+
# @private
|
7
|
+
class Reader
|
8
|
+
def self.[](definition)
|
9
|
+
new(definition).call
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
lines.flatten.compact.join("\n")
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def initialize(definition)
|
19
|
+
@target = definition.target
|
20
|
+
@ivar = definition.ivar
|
21
|
+
@null = definition.null
|
22
|
+
@reader = definition.reader
|
23
|
+
end
|
24
|
+
|
25
|
+
def lines
|
26
|
+
[undef_line, attribute_line, method_lines, type_line]
|
27
|
+
end
|
28
|
+
|
29
|
+
def undef_line
|
30
|
+
"undef :#{@target} if method_defined?(:#{@target})" \
|
31
|
+
" || private_method_defined?(:#{@target})" \
|
32
|
+
" || protected_method_defined?(:#{@target})"
|
33
|
+
end
|
34
|
+
|
35
|
+
def attribute_line
|
36
|
+
return unless @reader
|
37
|
+
|
38
|
+
"attr_reader :#{@target}" unless @null
|
39
|
+
end
|
40
|
+
|
41
|
+
def method_lines
|
42
|
+
return unless @reader
|
43
|
+
return unless @null
|
44
|
+
|
45
|
+
[
|
46
|
+
"def #{@target}",
|
47
|
+
" #{@ivar} unless Dry::Initializer::UNDEFINED == #{@ivar}",
|
48
|
+
"end"
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def type_line
|
53
|
+
"#{@reader} :#{@target}" if %i[private protected].include? @reader
|
54
|
+
end
|
55
|
+
end
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|
@@ -1,32 +1,38 @@
|
|
1
|
-
|
2
|
-
# @private
|
3
|
-
class Signature
|
4
|
-
def self.[](config)
|
5
|
-
new(config).call
|
6
|
-
end
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Builders
|
6
|
+
# @private
|
7
|
+
class Signature
|
8
|
+
def self.[](config)
|
9
|
+
new(config).call
|
10
|
+
end
|
11
11
|
|
12
|
-
|
12
|
+
def call
|
13
|
+
[*required_params, *optional_params, "*", options].compact.join(", ")
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
@config = config
|
16
|
-
@options = config.options.any?
|
17
|
-
@null = config.null ? 'Dry::Initializer::UNDEFINED' : 'nil'
|
18
|
-
end
|
16
|
+
private
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
def initialize(config)
|
19
|
+
@config = config
|
20
|
+
@options = config.options.any?
|
21
|
+
@null = config.null ? "Dry::Initializer::UNDEFINED" : "nil"
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def required_params
|
25
|
+
@config.params.reject(&:optional).map(&:source)
|
26
|
+
end
|
27
|
+
|
28
|
+
def optional_params
|
29
|
+
@config.params.select(&:optional).map { |rec| "#{rec.source} = #{@null}" }
|
30
|
+
end
|
27
31
|
|
28
|
-
|
29
|
-
|
32
|
+
def options
|
33
|
+
"**__dry_initializer_options__" if @options
|
34
|
+
end
|
35
|
+
end
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
# @private
|
6
|
+
module Builders
|
7
|
+
require_relative "builders/reader"
|
8
|
+
require_relative "builders/initializer"
|
9
|
+
end
|
6
10
|
end
|
7
11
|
end
|