1 package DX::Predicate::MemberAt;
3 use DX::Utils qw(:builders :dep_types);
4 use DX::ActionBuilder::ProxySetToAdd;
5 use DX::ActionBuilder::Null;
8 with 'DX::Role::Predicate';
10 sub _possible_resolution_list {
11 my ($self, @args) = @_;
12 my $rspace = $self->_resolution_space_for(@args);
13 return () unless my @members = @{$rspace->members};
15 $_->isa('DX::Resolution')
17 actions => $_->actions,
18 depends_on => $_->veracity_depends_on,
22 $_->veracity_depends_on_builder, @{$_->action_prototypes}
29 my ($inv, $type, @args) = @{$ap[$_]};
30 $inv->${\"action_for_${type}"}(@args, @{$cand[$_]});
33 depends_on => $db->(@cand),
35 } @{$_->implementation_candidates};
40 # member_at Dict Key Value
42 # Dict must be set to a dict (later maybe also an array and Key -> Index)
54 # Dict.Key != Value ->
60 # Set value to Dict.Key
62 # Key does not exist ->
68 # Failure on (exists Dict.Key, Value)
72 # Set value to ProxySetToAdd value
74 # Dict disallows add ->
76 # Failure on (exists Dict.Key)
80 # Value must also be unbound, because seriously?
82 # Set [Key, Value] to each pair in turn
84 sub _resolution_space_for {
85 my ($self, $dict, $key, $value) = @_;
87 die "Fucked" unless $dict->does('DX::Role::StructuredValue');
91 if (my $cur_val = $dict->get_member_at($key)) {
94 [ CONTENTS_OF ,=> $dict, $key->string_value ],
95 [ CONTENTS_OF ,=> $value ],
101 $cur_val->equals($value)
102 # Trivial resolution, D.K = V
105 veracity_depends_on => $deps,
112 geometry_depends_on => $deps,
119 geometry_depends_on => [
120 [ CONTENTS_OF ,=> $dict, $key->string_value ],
121 [ TYPE_OF ,=> $value ],
125 actions => [ $value->action_for_set_value($cur_val) ],
126 veracity_depends_on => $deps,
133 if ($dict->can_add_member) {
136 [ EXISTENCE_OF ,=> $dict, $key->string_value ],
137 [ TYPE_OF ,=> $value ],
140 if ($value->is_set) {
142 # If we get here, it means (currently) that we entered recheck
143 # due to the deletion of the key from the dict and should fail
144 # (or there's a bug in the compiler but let's hope not)
146 geometry_depends_on => $deps,
151 my @path = (@{$dict->value_path}, $key->string_value);
152 my $ab = DX::ActionBuilder::ProxySetToAdd->new(
153 target_path => \@path,
154 proxy_to => $dict->action_builder,
158 geometry_depends_on => $deps,
162 $value->action_for_set_value(
163 $value->but(action_builder => $ab),
166 # Veracity only depends on EXISTENCE_OF at this stage - if the
167 # $value is later set, recheck will lead us down a different path
168 # that will update those dependencies to include CONTENTS_OF
169 veracity_depends_on => $deps,
176 # Dict doesn't allow adding keys and key doesn't exist, so
177 # the contents of the value is completely irrelevant to the failure
179 geometry_depends_on => [
180 [ EXISTENCE_OF ,=> $dict, $key->string_value ],
187 die "Fucked" if $value->is_set; # +D -K +V ? seriously ?
189 # Laaater we may need to look at autovivifying an additional key/index
190 # ala ProxySetToAdd but I'm not 100% sure how that will make sense and
191 # premature generalisation is the root of all eval.
195 [ $dict->get_member_at($_) ],
196 ], map string($_), $dict->index_list;
199 geometry_depends_on => [
200 [ INDICES_OF ,=> $dict ],
201 [ TYPE_OF ,=> $key ],
202 [ TYPE_OF ,=> $value ],
206 action_prototypes => [
207 [ $key => 'set_value' ],
208 [ $value => 'set_value' ],
210 veracity_depends_on_builder => sub {
211 my ($this_key, $this_val) = map @$_, @_;
213 [ CONTENTS_OF ,=> $dict, $this_key->string_value ],
214 [ CONTENTS_OF ,=> $key ],
215 [ CONTENTS_OF ,=> $value ],
218 implementation_candidates => \@cand,