rewrite deparse system
[scpubgit/DX.git] / lib / DX / Role / BoundValueAction.pm
1 package DX::Role::BoundValueAction;
2
3 use DX::Role;
4
5 with 'DX::Role::Action';
6
7 has target_path => (is => 'ro', required => 1);
8
9 has bound_to_path => (is => 'ro', required => 1);
10
11 has rebind_path => (is => 'ro', required => 1);
12
13 has new_value => (is => 'ro', required => 1);
14
15 has inner_action => (is => 'ro', required => 1);
16
17 requires 'update_class';
18
19 sub for_deparse {
20   my ($self) = @_;
21   [ statement => [
22     [ symbol => (split('::',ref($self)))[-1] ],
23     [ value_path => $self->target_path ],
24     $self->new_value,
25   ] ];
26 }
27
28 sub dry_run {
29   my ($self, $hyp) = @_;
30   my ($outer_hyp, @inner_events) = $self->inner_action->dry_run(
31     $hyp->but(
32       action_applications => [ @{$hyp->action_applications}, $self ],
33     ),
34   );
35   my $new_bound_to = do {
36     my $targ = $outer_hyp->scope;
37     $targ = $targ->get_member_at($_) for @{$self->bound_to_path};
38     $targ;
39   };
40   my $new_ab = DX::ActionBuilder::BoundValue->new(
41     target_path => $self->target_path,
42     rebind_path => $self->rebind_path,
43     bound_to_path => $self->bound_to_path,
44     inner_action_builder => $new_bound_to->action_builder
45   );
46   my $value_with_ab = $new_ab->apply_to_value($self->new_value, $new_bound_to);
47   my ($scope, @events) = $outer_hyp->scope->apply_updates(
48                            $self->update_class->new(
49                              target_path => $self->target_path,
50                              new_value => $value_with_ab,
51                            )
52                          );
53   my $new_bound = do {
54     my $targ = $scope;
55     $targ = $targ->get_member_at($_) for @{$self->rebind_path};
56     $targ;
57   };
58   my @actions = @{$outer_hyp->actions};
59   foreach my $idx (0.. $#actions) {
60     my $act = $actions[$idx];
61     if (
62       $act->isa('DX::Action::BindValue')
63         and join("\0", @{$act->target_path})
64               eq join("\0", @{$self->rebind_path})
65     ) {
66       my $bind = splice @actions, $idx, 1;
67       push @actions, $bind->but(new_value => $new_bound);
68       last;
69     }
70   }
71   return (
72     $outer_hyp->but(scope => $scope, actions => \@actions),
73     @inner_events, @events
74   );
75 }
76
77 sub run { die }
78
79 1;