Skip to content

Commit 7e723da

Browse files
authored
Merge pull request #40 from v-kolesnikov/feature/constructor
Add Dry::Struct.constructor method
2 parents 5810752 + bdc15ae commit 7e723da

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

lib/dry/struct/class_interface.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'dry/equalizer'
33

44
require 'dry/struct/errors'
5+
require 'dry/struct/constructor'
56

67
module Dry
78
class Struct
@@ -120,6 +121,14 @@ def call(attributes = default_attributes)
120121
end
121122
alias_method :[], :call
122123

124+
# @param [#call,nil] constructor
125+
# @param [Hash] options
126+
# @param [#call,nil] block
127+
# @return [Dry::Struct::Constructor]
128+
def constructor(constructor = nil, **_options, &block)
129+
Struct::Constructor.new(self, fn: constructor || block)
130+
end
131+
123132
# Retrieves default attributes from defined {.schema}.
124133
# Used in a {Struct} constructor if no attributes provided to {.new}
125134
#

lib/dry/struct/constructor.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
module Dry
2+
class Struct
3+
class Constructor
4+
include Dry::Equalizer(:type)
5+
6+
# @return [#call]
7+
attr_reader :fn
8+
9+
# @return [#call]
10+
attr_reader :type
11+
12+
# @param [Struct] type
13+
# @param [Hash] options
14+
# @param [#call, nil] block
15+
def initialize(type, options = {}, &block)
16+
@type = type
17+
@fn = options.fetch(:fn, block)
18+
end
19+
20+
# @param [Object] input
21+
# @return [Object]
22+
def call(input)
23+
type[fn[input]]
24+
end
25+
alias_method :[], :call
26+
end
27+
end
28+
end

spec/shared/struct.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
end
9191
end
9292

93+
describe '.constructor' do
94+
it 'uses constructor function to process input' do
95+
expect(type.constructor(&:to_h)[jane.to_a]).to be_eql type[jane]
96+
end
97+
end
98+
9399
describe '.default?' do
94100
it 'is not a default' do
95101
expect(type).not_to be_default

0 commit comments

Comments
 (0)