Commit | Line | Data |
1e90aa03 |
1 | package DX::ActionBuilder::BoundValue; |
2 | |
3 | use DX::Action::SetBoundValue; |
5b066a1c |
4 | use DX::Action::AddBoundValue; |
6aa36401 |
5 | use DX::Utils qw(:event_types); |
1e90aa03 |
6 | use DX::Class; |
7 | |
8 | with 'DX::Role::ActionBuilder'; |
9 | |
2548ce61 |
10 | has target_path => (is => 'ro', required => 1, isa => ValuePath); |
1e90aa03 |
11 | |
2548ce61 |
12 | has rebind_path => (is => 'ro', required => 1, isa => ValuePath); |
1e90aa03 |
13 | |
2548ce61 |
14 | has bound_to_path => (is => 'ro', required => 1, isa => ValuePath); |
1e90aa03 |
15 | |
2548ce61 |
16 | has inner_action_builder => ( |
17 | is => 'ro', required => 1, isa => ActionBuilder |
18 | ); |
1e90aa03 |
19 | |
7f385fb2 |
20 | sub can_set_value { shift->inner_action_builder->can_set_value } |
21 | |
6aa36401 |
22 | sub 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 |
31 | sub 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 |
44 | sub can_add_member { shift->inner_action_builder->can_add_member } |
45 | |
6aa36401 |
46 | sub 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 |
55 | sub 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 |
70 | sub 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 |
89 | 1; |