format aperture in backtrack trace
[scpubgit/DX.git] / lib / DX / ActionBuilder / BoundValue.pm
CommitLineData
1e90aa03 1package DX::ActionBuilder::BoundValue;
2
3use DX::Action::SetBoundValue;
5b066a1c 4use DX::Action::AddBoundValue;
6aa36401 5use DX::Utils qw(:event_types);
1e90aa03 6use DX::Class;
7
8with 'DX::Role::ActionBuilder';
9
2548ce61 10has target_path => (is => 'ro', required => 1, isa => ValuePath);
1e90aa03 11
2548ce61 12has rebind_path => (is => 'ro', required => 1, isa => ValuePath);
1e90aa03 13
2548ce61 14has bound_to_path => (is => 'ro', required => 1, isa => ValuePath);
1e90aa03 15
2548ce61 16has inner_action_builder => (
17 is => 'ro', required => 1, isa => ActionBuilder
18);
1e90aa03 19
7f385fb2 20sub can_set_value { shift->inner_action_builder->can_set_value }
21
6aa36401 22sub aperture_for_set_value {
23 my ($self) = @_;
24 return [] unless $self->can_set_value;
25 [
26 [ VALUE_SET ,=> @{$self->target_path} ],
27 @{$self->inner_action_builder->aperture_for_set_value},
28 ]
29}
30
1e90aa03 31sub action_for_set_value {
32 my ($self, $value) = @_;
33 my $inner_action = $self->inner_action_builder->action_for_set_value($value);
34 return undef unless $inner_action;
35 DX::Action::SetBoundValue->new(
36 target_path => $self->target_path,
3a630a54 37 bound_to_path => $self->bound_to_path,
1e90aa03 38 rebind_path => $self->rebind_path,
3a630a54 39 new_value => $value,
1e90aa03 40 inner_action => $inner_action,
41 )
42}
43
1f3fa757 44sub can_add_member { shift->inner_action_builder->can_add_member }
45
6aa36401 46sub aperture_for_add_member {
47 my ($self, $at) = @_;
48 return [] unless $self->can_add_member;
49 [
50 [ VALUE_SET ,=> @{$self->target_path} ],
51 @{$self->inner_action_builder->aperture_for_add_member($at)},
52 ]
53}
54
5b066a1c 55sub action_for_add_member {
56 my ($self, $at, $value) = @_;
57 $at = $at->string_value if ref($at);
58 my $inner_action = $self->inner_action_builder
59 ->action_for_add_member($at, $value);
60 return undef unless $inner_action;
61 DX::Action::AddBoundValue->new(
62 target_path => [ @{$self->target_path}, $at ],
63 bound_to_path => [ @{$self->bound_to_path}, $at ],
64 rebind_path => $self->rebind_path,
65 new_value => $value,
66 inner_action => $inner_action
67 );
68}
69
3a630a54 70sub apply_to_value {
71 my ($self, $value, $inner_value) = @_;
7a5595d3 72 my $new_value = $value->but_set_action_builder($self);
3a630a54 73 return $new_value unless $new_value->isa('DX::Value::Dict');
74 my %m = %{$new_value->members};
75 return $new_value->but(
76 members => {
77 map {
78 my $this_inner = $inner_value->get_member_at($_);
79 ($_ => $self->but(
80 target_path => [ @{$self->target_path}, $_ ],
81 bound_to_path => [ @{$self->bound_to_path}, $_ ],
82 inner_action_builder => $this_inner->action_builder,
83 )->apply_to_value($m{$_}, $this_inner))
84 } keys %m
85 },
86 );
87}
88
1e90aa03 891;