ba92ab9a7edb9fcbee4bfb0745d1cc770967d6f8
[scpubgit/DX.git] / lib / DX / ActionBuilder / BoundValue.pm
1 package DX::ActionBuilder::BoundValue;
2
3 use DX::Action::SetBoundValue;
4 use DX::Action::AddBoundValue;
5 use DX::Class;
6
7 with 'DX::Role::ActionBuilder';
8
9 has target_path => (is => 'ro', required => 1);
10
11 has rebind_path => (is => 'ro', required => 1);
12
13 has bound_to_path => (is => 'ro', required => 1);
14
15 has inner_action_builder => (is => 'ro', required => 1);
16
17 sub can_set_value { shift->inner_action_builder->can_set_value }
18
19 sub action_for_set_value {
20   my ($self, $value) = @_;
21   my $inner_action = $self->inner_action_builder->action_for_set_value($value);
22   return undef unless $inner_action;
23   DX::Action::SetBoundValue->new(
24     target_path => $self->target_path,
25     bound_to_path => $self->bound_to_path,
26     rebind_path => $self->rebind_path,
27     new_value => $value,
28     inner_action => $inner_action,
29   )
30 }
31
32 sub can_add_member { shift->inner_action_builder->can_add_member }
33
34 sub action_for_add_member {
35   my ($self, $at, $value) = @_;
36   $at = $at->string_value if ref($at);
37   my $inner_action = $self->inner_action_builder
38                           ->action_for_add_member($at, $value);
39   return undef unless $inner_action;
40   DX::Action::AddBoundValue->new(
41     target_path => [ @{$self->target_path}, $at ],
42     bound_to_path => [ @{$self->bound_to_path}, $at ],
43     rebind_path => $self->rebind_path,
44     new_value => $value,
45     inner_action => $inner_action
46   );
47 }
48
49 sub apply_to_value {
50   my ($self, $value, $inner_value) = @_;
51   my $new_value = $value->but_set_action_builder($self);
52   return $new_value unless $new_value->isa('DX::Value::Dict');
53   my %m = %{$new_value->members};
54   return $new_value->but(
55     members => {
56       map {
57         my $this_inner = $inner_value->get_member_at($_);
58         ($_ => $self->but(
59                  target_path => [ @{$self->target_path}, $_ ],
60                  bound_to_path => [ @{$self->bound_to_path}, $_ ],
61                  inner_action_builder => $this_inner->action_builder,
62                )->apply_to_value($m{$_}, $this_inner))
63       } keys %m
64     },
65   );
66 }
67
68 1;