Commit | Line | Data |
5b066a1c |
1 | package DX::Role::BoundValueAction; |
2 | |
3 | use DX::Role; |
4 | |
5 | with 'DX::Role::Action'; |
6 | |
2548ce61 |
7 | has target_path => (is => 'ro', required => 1, isa => ValuePath); |
5b066a1c |
8 | |
2548ce61 |
9 | has bound_to_path => (is => 'ro', required => 1, isa => ValuePath); |
5b066a1c |
10 | |
2548ce61 |
11 | has rebind_path => (is => 'ro', required => 1, isa => ValuePath); |
5b066a1c |
12 | |
2548ce61 |
13 | has new_value => (is => 'ro', required => 1, isa => Value); |
5b066a1c |
14 | |
2548ce61 |
15 | has inner_action => (is => 'ro', required => 1, isa => Action); |
5b066a1c |
16 | |
17 | requires 'update_class'; |
18 | |
c25fbf05 |
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 | |
5b066a1c |
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; |