package DX::Role::Op;

use Moo::Role;

has next => (is => 'ro');

requires 'run';

sub but {
  my ($self, @but) = @_;
  $self->new(%$self, @but);
}

sub _expand_args {
  my ($self, $state, %spec) = @_;
  my %args;
  foreach my $key (keys %spec) {
    ($state, $args{$key}) = $self->_expand_argspec($state, $spec{$key});
  }
  return $state->expand_vars(%args);
}

sub _expand_argspec {
  my ($self, $state, $spec) = @_;
  if (!ref($spec)) {
    ($state->has_scope_var($spec)
      ? ($state, $state->scope_var($spec))
      : (map { $_, $_->scope_var($spec) } $state->assign_vars($spec => {})));
  } elsif (ref($spec) eq 'SCALAR' or ref($spec) eq 'REF') {
    return ($state, +{ bound_value => $$spec });
  } else {
    die "Argspec incomprehensible";
  }
}


1;
