add member proxy for new key + unset value
Matt S Trout [Sat, 12 Mar 2016 14:39:17 +0000 (14:39 +0000)]
lib/DX/ActionBuilder/ProxySetToAdd.pm [new file with mode: 0644]
lib/DX/Predicate/MemberAt.pm

diff --git a/lib/DX/ActionBuilder/ProxySetToAdd.pm b/lib/DX/ActionBuilder/ProxySetToAdd.pm
new file mode 100644 (file)
index 0000000..941ac70
--- /dev/null
@@ -0,0 +1,16 @@
+package DX::ActionBuilder::ProxySetToAdd;
+
+use DX::Class;
+
+with 'DX::Role::ActionBuilder';
+
+has target_path => (is => 'ro', required => 1);
+
+has proxy_to => (is => 'ro', required => 1);
+
+sub action_for_set_value {
+  my ($self, $value) = @_;
+  $self->proxy_to->action_for_add_member($self->target_path->[-1], $value);
+}
+
+1;
index 95a3f64..314f8e6 100644 (file)
@@ -1,6 +1,7 @@
 package DX::Predicate::MemberAt;
 
 use DX::Utils qw(step INDICES_OF EXISTENCE_OF CONTENTS_OF string);
+use DX::ActionBuilder::ProxySetToAdd;
 use DX::Class;
 
 with 'DX::Role::Predicate';
@@ -37,6 +38,31 @@ sub _possible_resolution_list {
                 ],
               ],
             );
+          } elsif (
+            !$value->is_set
+            and $value->action_builder->isa('DX::ActionBuilder::UnsetValue')
+            and my $p = $coll->identity_path
+          ) {
+            my @path = (@$p, $key->string_value);
+            my $ab = DX::ActionBuilder::ProxySetToAdd->new(
+              target_path => \@path,
+              proxy_to => $coll->action_builder,
+            );
+            my $set = $value->action_for_set_value(
+                        $value->but(
+                          identity_path => \@path,
+                          action_builder => $ab
+                        )
+                      );
+            step(
+              actions => [ $set ],
+              depends_on => [
+                [ $value =>
+                  [ CONTENTS_OF ,=> $coll, $key->string_value ],
+                  [ CONTENTS_OF ,=> $value ],
+                ],
+              ],
+            );
           } else {
             ()
           }