package DX::Op::Not;

use DX::Op::FromCode;
use DX::Var;
use DX::ArrayStream;
use DX::Op::Return;
use Moo;

with 'DX::Role::Op';

has body => (is => 'ro', required => 1);

sub run {
  my ($self, $state) = @_;
  my $var = DX::Var->new(id => "rule:not")
                   ->with_stream(DX::ArrayStream->from_array(
                       $self->body, DX::Op::Return->new
                     ));
  my $invoke = DX::Op::FromCode->new(
    code => sub {
      my ($self, $state) = @_;
      my $op = $var->bound_value;
      $state->then($op);
    }
  );
  $state->push_return_then($self->next, $invoke)->mark_choice($var);
}

1;
