Skip to content

Commit

Permalink
Switch node fix (#17)
Browse files Browse the repository at this point in the history
  • Loading branch information
EugZol authored Feb 6, 2024
1 parent 694c939 commit e8fd48c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
22 changes: 15 additions & 7 deletions lib/datacaster/switch_node.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
module Datacaster
class SwitchNode < Base
def initialize(base = nil, on_casters = [], else_caster = nil)
def initialize(base = nil, on_casters: [], else_caster: nil, pick_key: nil)
@base = base
@pick_key = pick_key

if Datacaster::Utils.pickable?(@base)
@base = Datacaster::Predefined.run { checked_key!(base) } &
Datacaster::Predefined.pick(base)
unless @pick_key.nil?
raise RuntimeError, "pick_key expected to be nil because #{@base.inspect} is pickable"
end
@pick_key = base
@base = Datacaster::Predefined.pick(base)
end

if !@base.nil? && !Datacaster.instance?(@base)
Expand Down Expand Up @@ -34,12 +38,12 @@ def on(caster_or_value, clause, strict: false)

clause = DefinitionDSL.expand(clause)

self.class.new(@base, @ons + [[caster, clause]], @else)
self.class.new(@base, on_casters: @ons + [[caster, clause]], else_caster: @else, pick_key: @pick_key)
end

def else(else_caster)
raise ArgumentError, "Datacaster: double else clause is not permitted", caller if @else
self.class.new(@base, @ons, else_caster)
self.class.new(@base, on_casters: @ons, else_caster: else_caster, pick_key: @pick_key)
end

def cast(object, runtime:)
Expand All @@ -59,7 +63,11 @@ def cast(object, runtime:)
result = check.with_runtime(runtime).(switch_result)
next unless result.valid?

return clause.with_runtime(runtime).(object)
if @pick_key.nil?
return clause.with_runtime(runtime).(object)
else
return runtime.checked_key!(@pick_key) { clause.with_runtime(runtime).(object) }
end
end

# all 'on'-s have failed
Expand All @@ -71,7 +79,7 @@ def cast(object, runtime:)
end

def inspect
"#<Datacaster::SwitchNode base: #{@base.inspect} on: #{@ons.inspect} else: #{@else.inspect}>"
"#<Datacaster::SwitchNode base: #{@base.inspect} on: #{@ons.inspect} else: #{@else.inspect} pick_key: #{@pick_key.inspect}>"
end
end
end
2 changes: 1 addition & 1 deletion lib/datacaster/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Datacaster
VERSION = "3.2.2"
VERSION = "3.2.3"
end
10 changes: 10 additions & 0 deletions spec/switch_node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,15 @@

expect(caster.(kind: 1, name: '1').to_dry_result).to eq Success(kind: 1, name: '1')
end

it 'marks matched-on value as checked with nested schemas' do
caster =
Datacaster.schema do
s = Datacaster.schema { string }
switch(:kind).on('person', hash_schema(kind: s))
end

expect(caster.(kind: 'person').to_dry_result).to eq Success(kind: 'person')
end
end
end

0 comments on commit e8fd48c

Please sign in to comment.