45e5abd92fc87e6fc2eadf72752d76c0def5d2b3
[scpubgit/DX.git] / lib / DX / ActionBuilder / Normal.pm
1 package DX::ActionBuilder::Normal;
2
3 use DX::Action::SetValue;
4 use DX::Action::AddValue;
5 use DX::Class;
6
7 with 'DX::Role::ActionBuilder';
8
9 has target_path => (is => 'ro', required => 1);
10
11 sub action_for_set_value {
12   my ($self, $value) = @_;
13   DX::Action::SetValue->new(
14     target_path => $self->target_path,
15     new_value => $self->apply_to_value($value),
16   );
17 }
18
19 sub action_for_add_member {
20   my ($self, $at, $value) = @_;
21   my $ab = $self->specialize_for_member($at);
22   DX::Action::AddValue->new(
23     target_path => $ab->target_path,
24     new_value => $ab->apply_to_value($value),
25   );
26 }
27
28 sub action_for_remove_member { die 'WHUT' }
29
30 sub apply_to_value {
31   my ($self, $value) = @_;
32   my $new_value = $value->but_set_action_builder($self)
33                         ->but_set_identity_path($self->target_path);
34   return $new_value unless $new_value->isa('DX::Value::Dict');
35   my %m = %{$new_value->members};
36   return $new_value->but(
37     members => {
38       map +($_ => $self->specialize_for_member($_)->apply_to_value($m{$_})),
39         keys %m,
40     },
41   );
42 }
43
44 sub specialize_for_member {
45   my ($self, $at) = @_;
46   $self->but(
47     target_path => [
48       @{$self->target_path},
49       (ref($at) ? $at->string_value : $at)
50     ],
51   );
52 }
53
54 1;