1 package DX::Predicate::MemberAt;
3 use DX::Utils qw(:builders :dep_types expand_deps);
4 use DX::ActionBuilder::ProxySetToAdd;
5 use DX::ActionBuilder::Null;
8 with 'DX::Role::Predicate';
10 # member_at Dict Key Value
12 # Dict must be set to a dict (later maybe also an array and Key -> Index)
24 # Dict.Key != Value ->
30 # Set value to Dict.Key
32 # Key does not exist ->
38 # Failure on (exists Dict.Key, Value)
42 # Set value to ProxySetToAdd value
44 # Dict disallows add ->
46 # Failure on (exists Dict.Key)
50 # Value must also be unbound, because seriously?
52 # Set [Key, Value] to each pair in turn
54 sub _resolution_space_for {
55 my ($self, $dict, $key, $value) = @_;
57 die "Fucked" unless $dict->does('DX::Role::StructuredValue');
61 if (my $cur_val = $dict->get_member_at($key)) {
63 my $deps = expand_deps([
64 [ CONTENTS_OF ,=> $dict, $key->string_value ],
65 [ CONTENTS_OF ,=> $value ],
71 $cur_val->equals($value)
72 # Trivial resolution, D.K = V
75 veracity_depends_on => $deps,
83 geometry_depends_on => $deps,
90 geometry_depends_on => expand_deps([
91 [ CONTENTS_OF ,=> $dict, $key->string_value ],
92 [ TYPE_OF ,=> $value ],
94 aperture => $value->aperture_for_set_value,
97 actions => [ $value->action_for_set_value($cur_val) ],
98 veracity_depends_on => $deps,
105 if ($dict->can_add_member) {
107 my $deps = expand_deps([
108 [ EXISTENCE_OF ,=> $dict, $key->string_value ],
109 [ TYPE_OF ,=> $value ],
112 if ($value->is_set) {
114 # If we get here, it means (currently) that we entered recheck
115 # due to the deletion of the key from the dict and should fail
116 # (or there's a bug in the compiler but let's hope not)
118 geometry_depends_on => $deps,
123 my @path = (@{$dict->value_path}, $key->string_value);
124 my $ab = DX::ActionBuilder::ProxySetToAdd->new(
125 target_path => \@path,
126 proxy_to => $dict->action_builder,
130 geometry_depends_on => $deps,
131 aperture => $value->aperture_for_set_value,
135 $value->action_for_set_value(
136 $value->but(action_builder => $ab),
139 # Veracity only depends on EXISTENCE_OF at this stage - if the
140 # $value is later set, recheck will lead us down a different path
141 # that will update those dependencies to include CONTENTS_OF
142 veracity_depends_on => $deps,
149 # Dict doesn't allow adding keys and key doesn't exist, so
150 # the contents of the value is completely irrelevant to the failure
152 geometry_depends_on => expand_deps([
153 [ EXISTENCE_OF ,=> $dict, $key->string_value ],
161 die "Fucked" if $value->is_set; # +D -K +V ? seriously ?
163 # Laaater we may need to look at autovivifying an additional key/index
164 # ala ProxySetToAdd but I'm not 100% sure how that will make sense and
165 # premature generalisation is the root of all eval.
169 [ $dict->get_member_at($_) ],
170 ], map string($_), $dict->index_list;
173 geometry_depends_on => expand_deps([
174 [ INDICES_OF ,=> $dict ],
175 [ TYPE_OF ,=> $key ],
176 [ TYPE_OF ,=> $value ],
178 aperture => [ map @{$_->aperture_for_set_value}, $key, $value ],
181 action_prototypes => [
182 [ $key => 'set_value' ],
183 [ $value => 'set_value' ],
185 veracity_depends_on_builder => sub {
186 my ($this_key, $this_val) = map @$_, @_;
188 [ CONTENTS_OF ,=> $dict, $this_key->string_value ],
189 [ CONTENTS_OF ,=> $key ],
190 [ CONTENTS_OF ,=> $value ],
193 implementation_candidates => \@cand,