File Coverage

blib/lib/Dallycot/AST/Zip.pm
Criterion Covered Total %
statement 21 68 30.8
branch 0 6 0.0
condition n/a
subroutine 7 16 43.7
pod 0 3 0.0
total 28 93 30.1


line stmt bran cond sub pod time code
1             package Dallycot::AST::Zip;
2             our $AUTHORITY = 'cpan:JSMITH';
3              
4             # ABSTRACT: Combines a set of collections into a collection of vectors
5              
6 23     23   12628 use strict;
  23         43  
  23         758  
7 23     23   170 use warnings;
  23         33  
  23         522  
8              
9 23     23   91 use utf8;
  23         29  
  23         106  
10 23     23   540 use parent 'Dallycot::AST';
  23         40  
  23         97  
11              
12 23     23   1158 use Promises qw(collect deferred);
  23         36  
  23         107  
13              
14 23     23   5779 use List::Util qw(max);
  23         40  
  23         1590  
15 23     23   116 use List::MoreUtils qw(all any each_array);
  23         33  
  23         207  
16              
17             sub to_string {
18 0     0 0   my ($self) = @_;
19 0           return '(' . join( ' Z ', map { $_->to_string } @{$self} ) . ')';
  0            
  0            
20             }
21              
22             sub to_rdf {
23 0     0 0   my($self, $model) = @_;
24              
25 0           return $model -> apply(
26             $model -> meta_uri('loc:zip'),
27             [ @$self ],
28             {}
29             );
30             # my $bnode = $model->bnode;
31             # $model -> add_type($bnode, 'loc:Zip');
32             #
33             # $model -> add_list($bnode, 'loc:expressions',
34             # map { $_ -> to_rdf($model) } @$self
35             # );
36             # return $bnode;
37             }
38              
39             sub execute {
40 0     0 0   my ( $self, $engine ) = @_;
41              
42             # produce a vector with the head of each thing
43             # then a tail promise for the rest
44             # unless we're all vectors, in which case zip everything up now!
45 0 0   0     if ( any { $_->isa('Dallycot::AST') } @$self ) {
  0 0          
    0          
46             return $engine->collect(@$self)->then(
47             sub {
48 0     0     my $newself = bless \@_ => __PACKAGE__;
49 0           $newself->execute($engine);
50             }
51 0           );
52             }
53 0     0     elsif ( all { $_->isa('Dallycot::Value::Vector') } @$self ) {
54              
55             # all vectors
56 0           my $it = each_arrayref(@$self);
57 0           my @results;
58 0           while ( my @vals = $it->() ) {
59 0           push @results, bless \@vals => 'Dallycot::Value::Vector';
60             }
61              
62 0           my $d = deferred;
63              
64 0           $d->resolve( bless \@results => 'Dallycot::Value::Vector' );
65              
66 0           return $d->promise;
67             }
68 0     0     elsif ( all { $_->isa('Dallycot::Value::String') } @$self ) {
69              
70             # all strings
71 0           my @sources = map { \{ $_->value } } @$self;
  0            
72 0           my $length = max( map { length $$_ } @sources );
  0            
73 0           my @results;
74 0           for ( my $idx = 0; $idx < $length; $idx++ ) {
75 0           my $s = join( "", map { substr( $$_, $idx, 1 ) } @sources );
  0            
76 0           push @results, Dallycot::Value::String->new($s);
77             }
78 0           my $d = deferred;
79              
80 0           $d->resolve( bless \@results => 'Dallycot::Value::Vector' );
81              
82 0           return $d->promise;
83             }
84             else {
85 0           my $d = deferred;
86              
87 0           collect( map { $_->head($engine) } @$self )->done(
88             sub {
89 0     0     my (@heads) = map {@$_} @_;
  0            
90 0           collect( map { $_->tail($engine) } @$self )->done(
91             sub {
92 0           my (@tails) = map {@$_} @_;
  0            
93 0           my $r;
94 0           $d->resolve(
95             $r = bless [
96             ( bless \@heads => 'Dallycot::Value::Vector' ),
97              
98             undef,
99              
100             Dallycot::Value::Lambda->new(
101             expression => ( bless \@tails => __PACKAGE__ ),
102             bindings => [],
103             bindings_with_defaults => [],
104             options => {}
105             )
106             ] => 'Dallycot::Value::Stream'
107             );
108             },
109             sub {
110 0           $d->reject(@_);
111             }
112 0           );
113             },
114             sub {
115 0     0     $d->reject(@_);
116             }
117 0           );
118              
119 0           return $d->promise;
120             }
121             }
122              
123             1;