dry-initializer 3.0.4 → 3.1.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/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
|