initial partial sketch
[scpubgit/DX.git] / lib / DX / Predicate / MemberAt.pm
1 package DX::Predicate::MemberAt;
2
3 use DX::Utils qw(step INDICES INDEX_EXISTS);
4 use DX::Class;
5
6 with 'DX::Role::Predicate';
7
8 # Thing I've ignored for the moment: set key, unset value
9 # which for an add should result in an _make_equal style
10 # bind-with-add-action I suspect, but I don't have a current use
11 # case so punting while I get everything-the-fuck-else done
12
13 sub _possible_resolution_list {
14   my ($self, $coll, $key, $value) = @_;
15   die "First argument to member_at must be a structured value"
16     unless $coll->does('DX::Role::StructuredValue');
17   return (
18     ($key->is_set
19       ? map $_->but_with_dependencies_on(
20           [ undef ,=> [ $coll, INDEX_EXISTS ,=> $key ], $key ]
21         ), do {
22           if (my $cur_val = $coll->get_member_at($key)) {
23             $self->_make_equal($cur_val, $value);
24           } elsif (
25             $value->is_set
26             and my $add = $coll->action_for_add_value($key, $value)
27           ) {
28             step(
29               actions => [ $add ],
30               depends_on => [
31                 [ $coll => [ $coll, $key ], $value ]
32               ],
33             );
34           } else {
35             ()
36           }
37         }
38       : ()
39     ),
40     ($key->can_set_value
41       ? map {
42           my $set_key = $key->action_for_set_value($_);
43           map $_->but_first($set_key)
44                 ->but_with_dependencies_on(
45                     [ undef ,=> [ $coll, INDEX_EXISTS ,=> $key ] ]
46                   ),
47             $self->_make_equal($coll->get_member_at($_), $value);
48         } $coll->index_list
49       : ()
50     ),
51   );
52 }
53
54 sub selection_depends_on {
55   my ($self, $coll, $key, $value) = @_;
56   [ [ $coll => ($key->can_set_value ? INDICES : (INDEX_EXISTS ,=> $key)) ],
57     $key,
58     $value,
59   ]
60 }
61
62 1;