package DX::ActionBuilder::Normal;
+use DX::Action::SetValue;
+use DX::Action::AddValue;
use DX::Class;
with 'DX::Role::ActionBuilder';
my ($self, $value) = @_;
DX::Action::SetValue->new(
target_path => $self->target_path,
- new_value => $value->but_set_action_builder($self)
+ new_value => $self->apply_to_value($value),
+ );
+}
+
+sub action_for_add_member {
+ my ($self, $at, $value) = @_;
+ my $ab = $self->specialize_for_member($at);
+ DX::Action::AddValue->new(
+ 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);
+ 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)
+ ],
);
}