my ($self, $value) = @_;
DX::Action::SetValue->new(
target_path => $self->target_path,
- new_value => $value->but_set_action_builder($self)
- ->but_set_identity_path($self->target_path)
+ new_value => $self->apply_to_value($value),
);
}
sub action_for_add_member {
my ($self, $at, $value) = @_;
- my @add_path = (@{$self->target_path}, ref($at) ? $at->string_value : $at);
+ my $ab = $self->specialize_for_member($at);
DX::Action::AddValue->new(
- target_path => \@add_path,
- new_value => $value->but_set_action_builder(
- $self->but(target_path => \@add_path)
- )->but_set_identity_path(\@add_path)
+ target_path => $ab->target_path,
+ new_value => $ab->apply_to_value($value),
);
}
sub action_for_remove_member { die 'WHUT' }
+sub apply_to_value {
+ my ($self, $value) = @_;
+ my $new_value = $value->but_set_action_builder($self)
+ ->but_set_identity_path($self->target_path);
+ return $new_value unless $new_value->isa('DX::Value::Dict');
+ my %m = %{$new_value->members};
+ return $new_value->but(
+ members => {
+ map +($_ => $self->specialize_for_member($_)->apply_to_value($m{$_})),
+ keys %m,
+ },
+ );
+}
+
+sub specialize_for_member {
+ my ($self, $at) = @_;
+ $self->but(
+ target_path => [
+ @{$self->target_path},
+ (ref($at) ? $at->string_value : $at)
+ ],
+ );
+}
+
1;