dc4ae782f2d68e5cf2aa36db9df03960eac1a27a
[scpubgit/DKit.git] / lib / DX / Op / Prop.pm
1 package DX::Op::Prop;
2
3 use Moo;
4
5 with 'DX::Role::Op';
6
7 has of => (is => 'ro', required => 1);
8 has name => (is => 'ro', required => 1);
9 has value => (is => 'ro', required => 1);
10
11 sub run {
12   my ($self, $state) = @_;
13   ($state, my %args) = $self->_expand_args(
14     $state, map +($_ => $self->$_), qw(of name value)
15   );
16   die "property name must be bound" unless $args{name}->is_bound;
17   my $name = $state->resolve_value($args{name});
18   if ($args{of}->is_bound) {
19     if ($args{value}->is_bound) {
20       if ($state->resolve_value($args{of})->$name
21           eq $state->resolve_value($args{value})) {
22         return $state->add_dependencies(
23                          $args{of}->id => $args{value}->id,
24                          $args{value}->id => $args{of}->id,
25                        )
26                      ->then($self->next);
27       }
28       return $state->backtrack;
29     }
30     my $value = $state->resolve_value($args{of});
31     if ($value->can("has_${name}") and not $value->${\"has_${name}"}) {
32       return $state->backtrack;
33     }
34     return $state->bind_value($args{value}->id, $value->$name)
35                  ->add_dependencies($args{value}->id => $args{of}->id)
36                  ->then($self->next);
37   }
38   die "Can't yet handle unbound 'of' argument";
39 }
40
41 1;