query/solve/ensure
[scpubgit/DKit.git] / lib / DX / Role / Op / FindIsh.pm
CommitLineData
f5a02c91 1package DX::Role::Op::FindIsh;
2
3use DX::Op::FromCode;
4use DX::Op::FindAllCollect;
5use DX::Var;
6use DX::OrderedSet;
7use DX::Op::Return;
8use Moo::Role;
9
10with 'DX::Role::Op';
11
12has var_name => (is => 'ro', required => 1);
13
14has body => (is => 'ro', required => 1);
15
16requires 'make_result_handler';
17
18sub run {
19 my ($self, $state) = @_;
20 my $values = [];
21 my $coll = DX::OrderedSet->new(values => $values);
22 my $collect = DX::Op::FindAllCollect->new(
23 var_name => $self->var_name,
24 into => $values
25 );
26 my $do_body = DX::Op::FromCode->new(
27 code => sub {
28 my ($self, $state) = @_;
29 $state->push_return_then($collect, $self->next);
30 },
31 next => $self->body
32 );
33 my $var = DX::Var->new(id => "rule:findall")
34 ->with_stream(DX::ArrayStream->from_array(
35 $do_body, DX::Op::Return->new
36 ));
37 my $invoke = DX::Op::FromCode->new(
38 code => sub {
39 my ($self, $state) = @_;
40 my $op = $state->resolve_value($var);
41 $state->then($op);
42 }
43 );
7ca660cb 44 my $allow = $state->allow_actions;
f5a02c91 45 my $ret = DX::Op::SetScope->new(
46 scope => $state->scope,
7ca660cb 47 next => DX::Op::FromCode->new(
48 code => sub {
49 my ($self, $state) = @_;
50 $state->but(allow_actions => $allow)
51 ->then($self->next);
52 },
53 next => $self->make_result_handler($coll),
54 )
f5a02c91 55 );
56 $state->assign_vars($self->var_name => {})
7ca660cb 57 ->but(allow_actions => 0)
f5a02c91 58 ->push_return_then($ret, $invoke)->mark_choice($var);
59}
60
611;