findall
[scpubgit/DKit.git] / lib / DX / Op / FindAll.pm
CommitLineData
138613a8 1package DX::Op::FindAll;
2
3use DX::Op::FromCode;
4use DX::Op::FindAllCollect;
5use DX::Var;
6use DX::OrderedSet;
7use DX::Op::Return;
8use Moo;
9
10with 'DX::Role::Op';
11
12has coll_name => (is => 'ro', required => 1);
13
14has var_name => (is => 'ro', required => 1);
15
16has body => (is => 'ro', required => 1);
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 );
44 my $coll_name = $self->coll_name;
45 my $ret = DX::Op::SetScope->new(
46 scope => $state->scope,
47 next => DX::Op::FromCode->new(
48 code => sub {
49 my ($self, $state) = @_;
50 $state->bind_value($state->scope->{$coll_name} => $coll)
51 ->then($self->next);
52 },
53 next => $self->next
54 )
55 );
56 $state->assign_vars($self->var_name => {})
57 ->push_return_then($ret, $invoke)->mark_choice($var);
58}
59
601;